1
This commit is contained in:
commit
2de36f3f48
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
363
.gitignore
vendored
Normal file
363
.gitignore
vendored
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Oo]ut/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
31
ScreenRecoder.sln
Normal file
31
ScreenRecoder.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.11.35312.102
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScreenRecoder", "ScreenRecoder\ScreenRecoder.vcxproj", "{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}.Release|x64.Build.0 = Release|x64
|
||||||
|
{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{F70F08D0-3A56-4E00-9941-A7B95D07EF2F}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {FAD60BC3-1307-4DAB-8F22-F5B51948EBC7}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
614
ScreenRecoder/CursorData.h
Normal file
614
ScreenRecoder/CursorData.h
Normal file
@ -0,0 +1,614 @@
|
|||||||
|
#pragma once
|
||||||
|
typedef struct CursorDefine
|
||||||
|
{
|
||||||
|
bool Center;
|
||||||
|
const unsigned int Data[32];
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32512 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b10000000000000000000000000000000,
|
||||||
|
0b11000000000000000000000000000000,
|
||||||
|
0b11100000000000000000000000000000,
|
||||||
|
0b11110000000000000000000000000000,
|
||||||
|
0b11111000000000000000000000000000,
|
||||||
|
0b11111100000000000000000000000000,
|
||||||
|
0b11111110000000000000000000000000,
|
||||||
|
0b11111111000000000000000000000000,
|
||||||
|
0b11111111100000000000000000000000,
|
||||||
|
0b11111111110000000000000000000000,
|
||||||
|
0b11111111111000000000000000000000,
|
||||||
|
0b11111111111100000000000000000000,
|
||||||
|
0b11111110000000000000000000000000,
|
||||||
|
0b11111110000000000000000000000000,
|
||||||
|
0b11001111000000000000000000000000,
|
||||||
|
0b10000111000000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000011110000000000000000000000,
|
||||||
|
0b00000001100000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32513 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000001110111000000000000,
|
||||||
|
0b00000000000001111111000000000000,
|
||||||
|
0b00000000000001111111000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000001111111000000000000,
|
||||||
|
0b00000000000001110111000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32514 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000011111111111111000000000,
|
||||||
|
0b00000000011111111111111000000000,
|
||||||
|
0b00000000011111111111111000000000,
|
||||||
|
0b00000000011111111111110000000000,
|
||||||
|
0b00000000011111111111110000000000,
|
||||||
|
0b00000000011111111111110000000000,
|
||||||
|
0b00000000011111111111110000000000,
|
||||||
|
0b00000000000111111111100000000000,
|
||||||
|
0b00000000000111111111000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000001111100000000000000,
|
||||||
|
0b00000000000001111100000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000011111111000000000000,
|
||||||
|
0b00000000000111111111100000000000,
|
||||||
|
0b00000000001111111111110000000000,
|
||||||
|
0b00000000011111111111110000000000,
|
||||||
|
0b00000000011111111111110000000000,
|
||||||
|
0b00000000011111111111110000000000,
|
||||||
|
0b00000000011111111111110000000000,
|
||||||
|
0b00000000011111111111111000000000,
|
||||||
|
0b00000000011111111111111000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32515 =
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000001111111111111111100000000,
|
||||||
|
0b00000001111111111111111100000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32516 =
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000010000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000001111100000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000111111111000000000000,
|
||||||
|
0b00000000000111111111100000000000,
|
||||||
|
0b00000000000111111111100000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32642 =
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000011111000000000000000000,
|
||||||
|
0b00000000011111000000000000000000,
|
||||||
|
0b00000000011111000000000000000000,
|
||||||
|
0b00000000011111000000000000000000,
|
||||||
|
0b00000000011111100000000000000000,
|
||||||
|
0b00000000000001110000000000000000,
|
||||||
|
0b00000000000000111000000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000001110010000000000,
|
||||||
|
0b00000000000000000111110000000000,
|
||||||
|
0b00000000000000000011110000000000,
|
||||||
|
0b00000000000000000011110000000000,
|
||||||
|
0b00000000000000000111110000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32643 =
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000111110000000000,
|
||||||
|
0b00000000000000000111110000000000,
|
||||||
|
0b00000000000000000011110000000000,
|
||||||
|
0b00000000000000000011110000000000,
|
||||||
|
0b00000000000000000111110000000000,
|
||||||
|
0b00000000000000001100000000000000,
|
||||||
|
0b00000000000000011100000000000000,
|
||||||
|
0b00000000000000110000000000000000,
|
||||||
|
0b00000000011001110000000000000000,
|
||||||
|
0b00000000011111000000000000000000,
|
||||||
|
0b00000000011111000000000000000000,
|
||||||
|
0b00000000011111000000000000000000,
|
||||||
|
0b00000000011111000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32644 =
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000011000000000011000000000,
|
||||||
|
0b00000000111000000000011100000000,
|
||||||
|
0b00000001111111111111111110000000,
|
||||||
|
0b00000001111111111111111100000000,
|
||||||
|
0b00000000111000000000011100000000,
|
||||||
|
0b00000000011000000000010000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32645 =
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000010000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000001111100000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000001111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000010000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32646 =
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000011000011000011000000000,
|
||||||
|
0b00000000111000011000011100000000,
|
||||||
|
0b00000001111111111111111110000000,
|
||||||
|
0b00000001111111111111111100000000,
|
||||||
|
0b00000000111000011000011100000000,
|
||||||
|
0b00000000011000011000010000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000000011000000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000001111100000000000000,
|
||||||
|
0b00000000000000111100000000000000,
|
||||||
|
0b00000000000000010000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32648 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000001111110000000000000,
|
||||||
|
0b00000000000111111111110000000000,
|
||||||
|
0b00000000001111111111110000000000,
|
||||||
|
0b00000000011111111111111100000000,
|
||||||
|
0b00000000111110000001111100000000,
|
||||||
|
0b00000001111111000000011110000000,
|
||||||
|
0b00000001111111000000001111000000,
|
||||||
|
0b00000011111111110000001111000000,
|
||||||
|
0b00000011110111110000000111000000,
|
||||||
|
0b00000011110011111100000111000000,
|
||||||
|
0b00000011110001111100000111000000,
|
||||||
|
0b00000011110000111111000111000000,
|
||||||
|
0b00000011110000011111001111000000,
|
||||||
|
0b00000001111000001111111111000000,
|
||||||
|
0b00000001111000000111111110000000,
|
||||||
|
0b00000001111110000011111110000000,
|
||||||
|
0b00000000011111000011111100000000,
|
||||||
|
0b00000000011111111111111000000000,
|
||||||
|
0b00000000000111111111110000000000,
|
||||||
|
0b00000000000011111111000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32649 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000011000000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111110000000000000000000000,
|
||||||
|
0b00000111111110000000000000000000,
|
||||||
|
0b00000111111111110000000000000000,
|
||||||
|
0b00000111111111111000000000000000,
|
||||||
|
0b00000111111111111000000000000000,
|
||||||
|
0b00000111111111111000000000000000,
|
||||||
|
0b11110111111111111000000000000000,
|
||||||
|
0b11111111111111111000000000000000,
|
||||||
|
0b11111111111111111000000000000000,
|
||||||
|
0b01111111111111111000000000000000,
|
||||||
|
0b00111111111111111000000000000000,
|
||||||
|
0b00011111111111111000000000000000,
|
||||||
|
0b00001111111111110000000000000000,
|
||||||
|
0b00000111111111110000000000000000,
|
||||||
|
0b00000111111111110000000000000000,
|
||||||
|
0b00000001111111000000000000000000,
|
||||||
|
0b00000000011110000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32650 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b11000000000000000000000000000000,
|
||||||
|
0b11000000000000000000000000000000,
|
||||||
|
0b11110000000011111111100000000000,
|
||||||
|
0b11110000000011111111100000000000,
|
||||||
|
0b11111100000011111111100000000000,
|
||||||
|
0b11111100000001111111000000000000,
|
||||||
|
0b11111111000001111111000000000000,
|
||||||
|
0b11111111000001111111000000000000,
|
||||||
|
0b11111111110001111111000000000000,
|
||||||
|
0b11111111110000011100000000000000,
|
||||||
|
0b11111111111100111110000000000000,
|
||||||
|
0b11111111111101111111000000000000,
|
||||||
|
0b11111111000001111111000000000000,
|
||||||
|
0b11101111000001111111000000000000,
|
||||||
|
0b11000111000001111111000000000000,
|
||||||
|
0b10000111100011111111100000000000,
|
||||||
|
0b00000111110011111111100000000000,
|
||||||
|
0b00000011110000000000000000000000,
|
||||||
|
0b00000001110000000000000000000000,
|
||||||
|
0b00000001110000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32651 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b11000000000000000000000000000000,
|
||||||
|
0b11000000000000000000000000000000,
|
||||||
|
0b11110000000000000000000000000000,
|
||||||
|
0b11110000000000000000000000000000,
|
||||||
|
0b11111100000011111111000000000000,
|
||||||
|
0b11111100000111111111000000000000,
|
||||||
|
0b11111111000111101111100000000000,
|
||||||
|
0b11111111000111101111100000000000,
|
||||||
|
0b11111111110111101111100000000000,
|
||||||
|
0b11111111110111111111000000000000,
|
||||||
|
0b11111111111100111110000000000000,
|
||||||
|
0b11111111111100111100000000000000,
|
||||||
|
0b11111111000000111100000000000000,
|
||||||
|
0b11101111000000011100000000000000,
|
||||||
|
0b11000111000001111110000000000000,
|
||||||
|
0b10000111100000111100000000000000,
|
||||||
|
0b00000111110000011100000000000000,
|
||||||
|
0b00000011110000000000000000000000,
|
||||||
|
0b00000001110000000000000000000000,
|
||||||
|
0b00000001110000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
0b00000000000000000000000000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32671 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000001100000000000000000000000,
|
||||||
|
0b00000011110000000000000000000000,
|
||||||
|
0b00000011110000000000000000000000,
|
||||||
|
0b00000011110000000000000000000000,
|
||||||
|
0b00000011110000000000000000000000,
|
||||||
|
0b00000011111100000000000000000000,
|
||||||
|
0b00000011111111100000000000000000,
|
||||||
|
0b00000011111111111100000000000000,
|
||||||
|
0b00000011111111111100000000000000,
|
||||||
|
0b00000011111111111100000000000000,
|
||||||
|
0b00000011111111111100000000000000,
|
||||||
|
0b01111011111111111100000000000000,
|
||||||
|
0b01111111111111111100000000000000,
|
||||||
|
0b01111111111111111100000000000000,
|
||||||
|
0b01111111111111111100000000000000,
|
||||||
|
0b00111111111111111100000000000000,
|
||||||
|
0b00011111111111111100000000000000,
|
||||||
|
0b00001111111111111101111110000000,
|
||||||
|
0b00001111111111111001111111000000,
|
||||||
|
0b00000111111111111111111111100000,
|
||||||
|
0b00000011111111111111111111100000,
|
||||||
|
0b00000000111111100111111111100000,
|
||||||
|
0b00000000000100000111111111100000,
|
||||||
|
0b00000000000000000111111111100000,
|
||||||
|
0b00000000000000000111111111100000,
|
||||||
|
0b00000000000000000011111111000000,
|
||||||
|
0b00000000000000000001111111000000,
|
||||||
|
0b00000000000000000001111110000000,
|
||||||
|
0b00000000000000000001111110000000,
|
||||||
|
0b00000000000000000000011100000000,
|
||||||
|
0b00000000000000000000011100000000,
|
||||||
|
0b00000000000000000000011000000000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const CursorDefine _CURSOR_32672 =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
0b00000011000000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111100000000000000000000000,
|
||||||
|
0b00000111111010000000000000000000,
|
||||||
|
0b00000111111111000000000000000000,
|
||||||
|
0b00000111111111111000000000000000,
|
||||||
|
0b00000111111111111000000000000000,
|
||||||
|
0b00000111111111111000000000000000,
|
||||||
|
0b01100111111111111000000000000000,
|
||||||
|
0b11111111111111111000000000000000,
|
||||||
|
0b11111111111111111000000000000000,
|
||||||
|
0b01111111111111111000000000000000,
|
||||||
|
0b01111111111111111000000000000000,
|
||||||
|
0b00111111111111111000000000000000,
|
||||||
|
0b00011111111111111000000000000000,
|
||||||
|
0b00001111111111110001111110000000,
|
||||||
|
0b00000111111111110001111110000000,
|
||||||
|
0b00000011111111100011111111000000,
|
||||||
|
0b00000001111111000011111111000000,
|
||||||
|
0b00000000000000000011111111000000,
|
||||||
|
0b00000000000000000011111111000000,
|
||||||
|
0b00000000000000000001111110000000,
|
||||||
|
0b00000000000000000001111110000000,
|
||||||
|
0b00000000000000000011111111100000,
|
||||||
|
0b00000000000000000111111111100000,
|
||||||
|
0b00000000000000000111111111100000,
|
||||||
|
0b00000000000000000111111111110000,
|
||||||
|
0b00000000000000001111111111110000,
|
||||||
|
0b00000000000000000111111111100000,
|
||||||
|
0b00000000000000000001111111000000,
|
||||||
|
}
|
||||||
|
};
|
74
ScreenRecoder/D3DX11.h
Normal file
74
ScreenRecoder/D3DX11.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) Microsoft Corporation. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// File: d3dx11.h
|
||||||
|
// Content: D3DX11 utility library
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __D3DX11_INTERNAL__
|
||||||
|
#error Incorrect D3DX11 header used
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __D3DX11_H__
|
||||||
|
#define __D3DX11_H__
|
||||||
|
|
||||||
|
|
||||||
|
// Defines
|
||||||
|
#include <limits.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#ifdef ALLOW_THROWING_NEW
|
||||||
|
#include <new>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define D3DX11_DEFAULT ((UINT) -1)
|
||||||
|
#define D3DX11_FROM_FILE ((UINT) -3)
|
||||||
|
#define DXGI_FORMAT_FROM_FILE ((DXGI_FORMAT) -3)
|
||||||
|
|
||||||
|
#ifndef D3DX11INLINE
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#if (_MSC_VER >= 1200)
|
||||||
|
#define D3DX11INLINE __forceinline
|
||||||
|
#else
|
||||||
|
#define D3DX11INLINE __inline
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define D3DX11INLINE inline
|
||||||
|
#else
|
||||||
|
#define D3DX11INLINE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Includes
|
||||||
|
#include "d3d11.h"
|
||||||
|
#include "d3dx11.h"
|
||||||
|
#include "d3dx11core.h"
|
||||||
|
#include "d3dx11tex.h"
|
||||||
|
#include "d3dx11async.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
#define _FACDD 0x876
|
||||||
|
#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code )
|
||||||
|
|
||||||
|
enum _D3DX11_ERR {
|
||||||
|
D3DX11_ERR_CANNOT_MODIFY_INDEX_BUFFER = MAKE_DDHRESULT(2900),
|
||||||
|
D3DX11_ERR_INVALID_MESH = MAKE_DDHRESULT(2901),
|
||||||
|
D3DX11_ERR_CANNOT_ATTR_SORT = MAKE_DDHRESULT(2902),
|
||||||
|
D3DX11_ERR_SKINNING_NOT_SUPPORTED = MAKE_DDHRESULT(2903),
|
||||||
|
D3DX11_ERR_TOO_MANY_INFLUENCES = MAKE_DDHRESULT(2904),
|
||||||
|
D3DX11_ERR_INVALID_DATA = MAKE_DDHRESULT(2905),
|
||||||
|
D3DX11_ERR_LOADED_MESH_HAS_NO_DATA = MAKE_DDHRESULT(2906),
|
||||||
|
D3DX11_ERR_DUPLICATE_NAMED_FRAGMENT = MAKE_DDHRESULT(2907),
|
||||||
|
D3DX11_ERR_CANNOT_REMOVE_LAST_ITEM = MAKE_DDHRESULT(2908),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__D3DX11_H__
|
||||||
|
|
164
ScreenRecoder/D3DX11async.h
Normal file
164
ScreenRecoder/D3DX11async.h
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// File: D3DX11Async.h
|
||||||
|
// Content: D3DX11 Asynchronous Shader loaders / compilers
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __D3DX11ASYNC_H__
|
||||||
|
#define __D3DX11ASYNC_H__
|
||||||
|
|
||||||
|
#include "d3dx11.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11Compile:
|
||||||
|
// ------------------
|
||||||
|
// Compiles an effect or shader.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// pSrcFile
|
||||||
|
// Source file name.
|
||||||
|
// hSrcModule
|
||||||
|
// Module handle. if NULL, current module will be used.
|
||||||
|
// pSrcResource
|
||||||
|
// Resource name in module.
|
||||||
|
// pSrcData
|
||||||
|
// Pointer to source code.
|
||||||
|
// SrcDataLen
|
||||||
|
// Size of source code, in bytes.
|
||||||
|
// pDefines
|
||||||
|
// Optional NULL-terminated array of preprocessor macro definitions.
|
||||||
|
// pInclude
|
||||||
|
// Optional interface pointer to use for handling #include directives.
|
||||||
|
// If this parameter is NULL, #includes will be honored when compiling
|
||||||
|
// from file, and will error when compiling from resource or memory.
|
||||||
|
// pFunctionName
|
||||||
|
// Name of the entrypoint function where execution should begin.
|
||||||
|
// pProfile
|
||||||
|
// Instruction set to be used when generating code. Currently supported
|
||||||
|
// profiles are "vs_1_1", "vs_2_0", "vs_2_a", "vs_2_sw", "vs_3_0",
|
||||||
|
// "vs_3_sw", "vs_4_0", "vs_4_1",
|
||||||
|
// "ps_2_0", "ps_2_a", "ps_2_b", "ps_2_sw", "ps_3_0",
|
||||||
|
// "ps_3_sw", "ps_4_0", "ps_4_1",
|
||||||
|
// "gs_4_0", "gs_4_1",
|
||||||
|
// "tx_1_0",
|
||||||
|
// "fx_4_0", "fx_4_1"
|
||||||
|
// Note that this entrypoint does not compile fx_2_0 targets, for that
|
||||||
|
// you need to use the D3DX9 function.
|
||||||
|
// Flags1
|
||||||
|
// See D3D10_SHADER_xxx flags.
|
||||||
|
// Flags2
|
||||||
|
// See D3D10_EFFECT_xxx flags.
|
||||||
|
// ppShader
|
||||||
|
// Returns a buffer containing the created shader. This buffer contains
|
||||||
|
// the compiled shader code, as well as any embedded debug and symbol
|
||||||
|
// table info. (See D3D10GetShaderConstantTable)
|
||||||
|
// ppErrorMsgs
|
||||||
|
// Returns a buffer containing a listing of errors and warnings that were
|
||||||
|
// encountered during the compile. If you are running in a debugger,
|
||||||
|
// these are the same messages you will see in your debug output.
|
||||||
|
// pHResult
|
||||||
|
// Pointer to a memory location to receive the return value upon completion.
|
||||||
|
// Maybe NULL if not needed.
|
||||||
|
// If pPump != NULL, pHResult must be a valid memory location until the
|
||||||
|
// the asynchronous execution completes.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CompileFromFileA(LPCSTR pSrcFile,CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude,
|
||||||
|
LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CompileFromFileW(LPCWSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude,
|
||||||
|
LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11CompileFromFile D3DX11CompileFromFileW
|
||||||
|
#else
|
||||||
|
#define D3DX11CompileFromFile D3DX11CompileFromFileA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CompileFromResourceA(HMODULE hSrcModule, LPCSTR pSrcResource, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines,
|
||||||
|
LPD3D10INCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CompileFromResourceW(HMODULE hSrcModule, LPCWSTR pSrcResource, LPCWSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines,
|
||||||
|
LPD3D10INCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11CompileFromResource D3DX11CompileFromResourceW
|
||||||
|
#else
|
||||||
|
#define D3DX11CompileFromResource D3DX11CompileFromResourceA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CompileFromMemory(LPCSTR pSrcData, SIZE_T SrcDataLen, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude,
|
||||||
|
LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11PreprocessShaderFromFileA(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines,
|
||||||
|
LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11PreprocessShaderFromFileW(LPCWSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines,
|
||||||
|
LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11PreprocessShaderFromMemory(LPCSTR pSrcData, SIZE_T SrcDataSize, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines,
|
||||||
|
LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11PreprocessShaderFromResourceA(HMODULE hModule, LPCSTR pResourceName, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines,
|
||||||
|
LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11PreprocessShaderFromResourceW(HMODULE hModule, LPCWSTR pResourceName, LPCWSTR pSrcFileName, CONST D3D10_SHADER_MACRO* pDefines,
|
||||||
|
LPD3D10INCLUDE pInclude, ID3DX11ThreadPump *pPump, ID3D10Blob** ppShaderText, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11PreprocessShaderFromFile D3DX11PreprocessShaderFromFileW
|
||||||
|
#define D3DX11PreprocessShaderFromResource D3DX11PreprocessShaderFromResourceW
|
||||||
|
#else
|
||||||
|
#define D3DX11PreprocessShaderFromFile D3DX11PreprocessShaderFromFileA
|
||||||
|
#define D3DX11PreprocessShaderFromResource D3DX11PreprocessShaderFromResourceA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Async processors
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncCompilerProcessor(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude,
|
||||||
|
LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2,
|
||||||
|
ID3D10Blob **ppCompiledShader, ID3D10Blob **ppErrorBuffer, ID3DX11DataProcessor **ppProcessor);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncShaderPreprocessProcessor(LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude,
|
||||||
|
ID3D10Blob** ppShaderText, ID3D10Blob **ppErrorBuffer, ID3DX11DataProcessor **ppProcessor);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11 Asynchronous texture I/O (advanced mode)
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncFileLoaderW(LPCWSTR pFileName, ID3DX11DataLoader **ppDataLoader);
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncFileLoaderA(LPCSTR pFileName, ID3DX11DataLoader **ppDataLoader);
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncMemoryLoader(LPCVOID pData, SIZE_T cbData, ID3DX11DataLoader **ppDataLoader);
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncResourceLoaderW(HMODULE hSrcModule, LPCWSTR pSrcResource, ID3DX11DataLoader **ppDataLoader);
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncResourceLoaderA(HMODULE hSrcModule, LPCSTR pSrcResource, ID3DX11DataLoader **ppDataLoader);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11CreateAsyncFileLoader D3DX11CreateAsyncFileLoaderW
|
||||||
|
#define D3DX11CreateAsyncResourceLoader D3DX11CreateAsyncResourceLoaderW
|
||||||
|
#else
|
||||||
|
#define D3DX11CreateAsyncFileLoader D3DX11CreateAsyncFileLoaderA
|
||||||
|
#define D3DX11CreateAsyncResourceLoader D3DX11CreateAsyncResourceLoaderA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncTextureProcessor(ID3D11Device *pDevice, D3DX11_IMAGE_LOAD_INFO *pLoadInfo, ID3DX11DataProcessor **ppDataProcessor);
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncTextureInfoProcessor(D3DX11_IMAGE_INFO *pImageInfo, ID3DX11DataProcessor **ppDataProcessor);
|
||||||
|
HRESULT WINAPI D3DX11CreateAsyncShaderResourceViewProcessor(ID3D11Device *pDevice, D3DX11_IMAGE_LOAD_INFO *pLoadInfo, ID3DX11DataProcessor **ppDataProcessor);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
#endif //__D3DX11ASYNC_H__
|
||||||
|
|
||||||
|
|
128
ScreenRecoder/D3DX11core.h
Normal file
128
ScreenRecoder/D3DX11core.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) Microsoft Corporation. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// File: d3dx11core.h
|
||||||
|
// Content: D3DX11 core types and functions
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "d3dx11.h"
|
||||||
|
|
||||||
|
#ifndef __D3DX11CORE_H__
|
||||||
|
#define __D3DX11CORE_H__
|
||||||
|
|
||||||
|
// Current name of the DLL shipped in the same SDK as this header.
|
||||||
|
|
||||||
|
|
||||||
|
#define D3DX11_DLL_W L"d3dx11_43.dll"
|
||||||
|
#define D3DX11_DLL_A "d3dx11_43.dll"
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11_DLL D3DX11_DLL_W
|
||||||
|
#else
|
||||||
|
#define D3DX11_DLL D3DX11_DLL_A
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// D3DX11_SDK_VERSION:
|
||||||
|
// -----------------
|
||||||
|
// This identifier is passed to D3DX11CheckVersion in order to ensure that an
|
||||||
|
// application was built against the correct header files and lib files.
|
||||||
|
// This number is incremented whenever a header (or other) change would
|
||||||
|
// require applications to be rebuilt. If the version doesn't match,
|
||||||
|
// D3DX11CreateVersion will return FALSE. (The number itself has no meaning.)
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#define D3DX11_SDK_VERSION 43
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef D3D_DIAG_DLL
|
||||||
|
BOOL WINAPI D3DX11DebugMute(BOOL Mute);
|
||||||
|
#endif
|
||||||
|
HRESULT WINAPI D3DX11CheckVersion(UINT D3DSdkVersion, UINT D3DX11SdkVersion);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ID3DX11ThreadPump:
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#undef INTERFACE
|
||||||
|
#define INTERFACE ID3DX11DataLoader
|
||||||
|
|
||||||
|
DECLARE_INTERFACE(ID3DX11DataLoader)
|
||||||
|
{
|
||||||
|
STDMETHOD(Load)(THIS) PURE;
|
||||||
|
STDMETHOD(Decompress)(THIS_ void **ppData, SIZE_T *pcBytes) PURE;
|
||||||
|
STDMETHOD(Destroy)(THIS) PURE;
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef INTERFACE
|
||||||
|
#define INTERFACE ID3DX11DataProcessor
|
||||||
|
|
||||||
|
DECLARE_INTERFACE(ID3DX11DataProcessor)
|
||||||
|
{
|
||||||
|
STDMETHOD(Process)(THIS_ void *pData, SIZE_T cBytes) PURE;
|
||||||
|
STDMETHOD(CreateDeviceObject)(THIS_ void **ppDataObject) PURE;
|
||||||
|
STDMETHOD(Destroy)(THIS) PURE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// {C93FECFA-6967-478a-ABBC-402D90621FCB}
|
||||||
|
DEFINE_GUID(IID_ID3DX11ThreadPump,
|
||||||
|
0xc93fecfa, 0x6967, 0x478a, 0xab, 0xbc, 0x40, 0x2d, 0x90, 0x62, 0x1f, 0xcb);
|
||||||
|
|
||||||
|
#undef INTERFACE
|
||||||
|
#define INTERFACE ID3DX11ThreadPump
|
||||||
|
|
||||||
|
DECLARE_INTERFACE_(ID3DX11ThreadPump, IUnknown)
|
||||||
|
{
|
||||||
|
// IUnknown
|
||||||
|
STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE;
|
||||||
|
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
|
||||||
|
STDMETHOD_(ULONG, Release)(THIS) PURE;
|
||||||
|
|
||||||
|
// ID3DX11ThreadPump
|
||||||
|
STDMETHOD(AddWorkItem)(THIS_ ID3DX11DataLoader *pDataLoader, ID3DX11DataProcessor *pDataProcessor, HRESULT *pHResult, void **ppDeviceObject) PURE;
|
||||||
|
STDMETHOD_(UINT, GetWorkItemCount)(THIS) PURE;
|
||||||
|
|
||||||
|
STDMETHOD(WaitForAllItems)(THIS) PURE;
|
||||||
|
STDMETHOD(ProcessDeviceWorkItems)(THIS_ UINT iWorkItemCount);
|
||||||
|
|
||||||
|
STDMETHOD(PurgeAllItems)(THIS) PURE;
|
||||||
|
STDMETHOD(GetQueueStatus)(THIS_ UINT *pIoQueue, UINT *pProcessQueue, UINT *pDeviceQueue) PURE;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11CreateThreadPump(UINT cIoThreads, UINT cProcThreads, ID3DX11ThreadPump **ppThreadPump);
|
||||||
|
|
||||||
|
HRESULT WINAPI D3DX11UnsetAllDeviceObjects(ID3D11DeviceContext *pContext);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define _FACD3D 0x876
|
||||||
|
#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code )
|
||||||
|
#define MAKE_D3DSTATUS( code ) MAKE_HRESULT( 0, _FACD3D, code )
|
||||||
|
|
||||||
|
#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156)
|
||||||
|
#define D3DERR_WASSTILLDRAWING MAKE_D3DHRESULT(540)
|
||||||
|
|
||||||
|
#endif //__D3DX11CORE_H__
|
||||||
|
|
772
ScreenRecoder/D3DX11tex.h
Normal file
772
ScreenRecoder/D3DX11tex.h
Normal file
@ -0,0 +1,772 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) Microsoft Corporation. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// File: d3dx11tex.h
|
||||||
|
// Content: D3DX11 texturing APIs
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "d3dx11.h"
|
||||||
|
|
||||||
|
#ifndef __D3DX11TEX_H__
|
||||||
|
#define __D3DX11TEX_H__
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11_FILTER flags:
|
||||||
|
// ------------------
|
||||||
|
//
|
||||||
|
// A valid filter must contain one of these values:
|
||||||
|
//
|
||||||
|
// D3DX11_FILTER_NONE
|
||||||
|
// No scaling or filtering will take place. Pixels outside the bounds
|
||||||
|
// of the source image are assumed to be transparent black.
|
||||||
|
// D3DX11_FILTER_POINT
|
||||||
|
// Each destination pixel is computed by sampling the nearest pixel
|
||||||
|
// from the source image.
|
||||||
|
// D3DX11_FILTER_LINEAR
|
||||||
|
// Each destination pixel is computed by linearly interpolating between
|
||||||
|
// the nearest pixels in the source image. This filter works best
|
||||||
|
// when the scale on each axis is less than 2.
|
||||||
|
// D3DX11_FILTER_TRIANGLE
|
||||||
|
// Every pixel in the source image contributes equally to the
|
||||||
|
// destination image. This is the slowest of all the filters.
|
||||||
|
// D3DX11_FILTER_BOX
|
||||||
|
// Each pixel is computed by averaging a 2x2(x2) box pixels from
|
||||||
|
// the source image. Only works when the dimensions of the
|
||||||
|
// destination are half those of the source. (as with mip maps)
|
||||||
|
//
|
||||||
|
// And can be OR'd with any of these optional flags:
|
||||||
|
//
|
||||||
|
// D3DX11_FILTER_MIRROR_U
|
||||||
|
// Indicates that pixels off the edge of the texture on the U-axis
|
||||||
|
// should be mirrored, not wraped.
|
||||||
|
// D3DX11_FILTER_MIRROR_V
|
||||||
|
// Indicates that pixels off the edge of the texture on the V-axis
|
||||||
|
// should be mirrored, not wraped.
|
||||||
|
// D3DX11_FILTER_MIRROR_W
|
||||||
|
// Indicates that pixels off the edge of the texture on the W-axis
|
||||||
|
// should be mirrored, not wraped.
|
||||||
|
// D3DX11_FILTER_MIRROR
|
||||||
|
// Same as specifying D3DX11_FILTER_MIRROR_U | D3DX11_FILTER_MIRROR_V |
|
||||||
|
// D3DX11_FILTER_MIRROR_V
|
||||||
|
// D3DX11_FILTER_DITHER
|
||||||
|
// Dithers the resulting image using a 4x4 order dither pattern.
|
||||||
|
// D3DX11_FILTER_SRGB_IN
|
||||||
|
// Denotes that the input data is in sRGB (gamma 2.2) colorspace.
|
||||||
|
// D3DX11_FILTER_SRGB_OUT
|
||||||
|
// Denotes that the output data is in sRGB (gamma 2.2) colorspace.
|
||||||
|
// D3DX11_FILTER_SRGB
|
||||||
|
// Same as specifying D3DX11_FILTER_SRGB_IN | D3DX11_FILTER_SRGB_OUT
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef enum D3DX11_FILTER_FLAG
|
||||||
|
{
|
||||||
|
D3DX11_FILTER_NONE = (1 << 0),
|
||||||
|
D3DX11_FILTER_POINT = (2 << 0),
|
||||||
|
D3DX11_FILTER_LINEAR = (3 << 0),
|
||||||
|
D3DX11_FILTER_TRIANGLE = (4 << 0),
|
||||||
|
D3DX11_FILTER_BOX = (5 << 0),
|
||||||
|
|
||||||
|
D3DX11_FILTER_MIRROR_U = (1 << 16),
|
||||||
|
D3DX11_FILTER_MIRROR_V = (2 << 16),
|
||||||
|
D3DX11_FILTER_MIRROR_W = (4 << 16),
|
||||||
|
D3DX11_FILTER_MIRROR = (7 << 16),
|
||||||
|
|
||||||
|
D3DX11_FILTER_DITHER = (1 << 19),
|
||||||
|
D3DX11_FILTER_DITHER_DIFFUSION= (2 << 19),
|
||||||
|
|
||||||
|
D3DX11_FILTER_SRGB_IN = (1 << 21),
|
||||||
|
D3DX11_FILTER_SRGB_OUT = (2 << 21),
|
||||||
|
D3DX11_FILTER_SRGB = (3 << 21),
|
||||||
|
} D3DX11_FILTER_FLAG;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11_NORMALMAP flags:
|
||||||
|
// ---------------------
|
||||||
|
// These flags are used to control how D3DX11ComputeNormalMap generates normal
|
||||||
|
// maps. Any number of these flags may be OR'd together in any combination.
|
||||||
|
//
|
||||||
|
// D3DX11_NORMALMAP_MIRROR_U
|
||||||
|
// Indicates that pixels off the edge of the texture on the U-axis
|
||||||
|
// should be mirrored, not wraped.
|
||||||
|
// D3DX11_NORMALMAP_MIRROR_V
|
||||||
|
// Indicates that pixels off the edge of the texture on the V-axis
|
||||||
|
// should be mirrored, not wraped.
|
||||||
|
// D3DX11_NORMALMAP_MIRROR
|
||||||
|
// Same as specifying D3DX11_NORMALMAP_MIRROR_U | D3DX11_NORMALMAP_MIRROR_V
|
||||||
|
// D3DX11_NORMALMAP_INVERTSIGN
|
||||||
|
// Inverts the direction of each normal
|
||||||
|
// D3DX11_NORMALMAP_COMPUTE_OCCLUSION
|
||||||
|
// Compute the per pixel Occlusion term and encodes it into the alpha.
|
||||||
|
// An Alpha of 1 means that the pixel is not obscured in anyway, and
|
||||||
|
// an alpha of 0 would mean that the pixel is completly obscured.
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef enum D3DX11_NORMALMAP_FLAG
|
||||||
|
{
|
||||||
|
D3DX11_NORMALMAP_MIRROR_U = (1 << 16),
|
||||||
|
D3DX11_NORMALMAP_MIRROR_V = (2 << 16),
|
||||||
|
D3DX11_NORMALMAP_MIRROR = (3 << 16),
|
||||||
|
D3DX11_NORMALMAP_INVERTSIGN = (8 << 16),
|
||||||
|
D3DX11_NORMALMAP_COMPUTE_OCCLUSION = (16 << 16),
|
||||||
|
} D3DX11_NORMALMAP_FLAG;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11_CHANNEL flags:
|
||||||
|
// -------------------
|
||||||
|
// These flags are used by functions which operate on or more channels
|
||||||
|
// in a texture.
|
||||||
|
//
|
||||||
|
// D3DX11_CHANNEL_RED
|
||||||
|
// Indicates the red channel should be used
|
||||||
|
// D3DX11_CHANNEL_BLUE
|
||||||
|
// Indicates the blue channel should be used
|
||||||
|
// D3DX11_CHANNEL_GREEN
|
||||||
|
// Indicates the green channel should be used
|
||||||
|
// D3DX11_CHANNEL_ALPHA
|
||||||
|
// Indicates the alpha channel should be used
|
||||||
|
// D3DX11_CHANNEL_LUMINANCE
|
||||||
|
// Indicates the luminaces of the red green and blue channels should be
|
||||||
|
// used.
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef enum D3DX11_CHANNEL_FLAG
|
||||||
|
{
|
||||||
|
D3DX11_CHANNEL_RED = (1 << 0),
|
||||||
|
D3DX11_CHANNEL_BLUE = (1 << 1),
|
||||||
|
D3DX11_CHANNEL_GREEN = (1 << 2),
|
||||||
|
D3DX11_CHANNEL_ALPHA = (1 << 3),
|
||||||
|
D3DX11_CHANNEL_LUMINANCE = (1 << 4),
|
||||||
|
} D3DX11_CHANNEL_FLAG;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11_IMAGE_FILE_FORMAT:
|
||||||
|
// ---------------------
|
||||||
|
// This enum is used to describe supported image file formats.
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef enum D3DX11_IMAGE_FILE_FORMAT
|
||||||
|
{
|
||||||
|
D3DX11_IFF_BMP = 0,
|
||||||
|
D3DX11_IFF_JPG = 1,
|
||||||
|
D3DX11_IFF_PNG = 3,
|
||||||
|
D3DX11_IFF_DDS = 4,
|
||||||
|
D3DX11_IFF_TIFF = 10,
|
||||||
|
D3DX11_IFF_GIF = 11,
|
||||||
|
D3DX11_IFF_WMP = 12,
|
||||||
|
D3DX11_IFF_FORCE_DWORD = 0x7fffffff
|
||||||
|
|
||||||
|
} D3DX11_IMAGE_FILE_FORMAT;
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11_SAVE_TEXTURE_FLAG:
|
||||||
|
// ---------------------
|
||||||
|
// This enum is used to support texture saving options.
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef enum D3DX11_SAVE_TEXTURE_FLAG
|
||||||
|
{
|
||||||
|
D3DX11_STF_USEINPUTBLOB = 0x0001,
|
||||||
|
} D3DX11_SAVE_TEXTURE_FLAG;
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11_IMAGE_INFO:
|
||||||
|
// ---------------
|
||||||
|
// This structure is used to return a rough description of what the
|
||||||
|
// the original contents of an image file looked like.
|
||||||
|
//
|
||||||
|
// Width
|
||||||
|
// Width of original image in pixels
|
||||||
|
// Height
|
||||||
|
// Height of original image in pixels
|
||||||
|
// Depth
|
||||||
|
// Depth of original image in pixels
|
||||||
|
// ArraySize
|
||||||
|
// Array size in textures
|
||||||
|
// MipLevels
|
||||||
|
// Number of mip levels in original image
|
||||||
|
// MiscFlags
|
||||||
|
// Miscellaneous flags
|
||||||
|
// Format
|
||||||
|
// D3D format which most closely describes the data in original image
|
||||||
|
// ResourceDimension
|
||||||
|
// D3D11_RESOURCE_DIMENSION representing the dimension of texture stored in the file.
|
||||||
|
// D3D11_RESOURCE_DIMENSION_TEXTURE1D, 2D, 3D
|
||||||
|
// ImageFileFormat
|
||||||
|
// D3DX11_IMAGE_FILE_FORMAT representing the format of the image file.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct D3DX11_IMAGE_INFO
|
||||||
|
{
|
||||||
|
UINT Width;
|
||||||
|
UINT Height;
|
||||||
|
UINT Depth;
|
||||||
|
UINT ArraySize;
|
||||||
|
UINT MipLevels;
|
||||||
|
UINT MiscFlags;
|
||||||
|
DXGI_FORMAT Format;
|
||||||
|
D3D11_RESOURCE_DIMENSION ResourceDimension;
|
||||||
|
D3DX11_IMAGE_FILE_FORMAT ImageFileFormat;
|
||||||
|
} D3DX11_IMAGE_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Image File APIs ///////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11_IMAGE_LOAD_INFO:
|
||||||
|
// ---------------
|
||||||
|
// This structure can be optionally passed in to texture loader APIs to
|
||||||
|
// control how textures get loaded. Pass in D3DX11_DEFAULT for any of these
|
||||||
|
// to have D3DX automatically pick defaults based on the source file.
|
||||||
|
//
|
||||||
|
// Width
|
||||||
|
// Rescale texture to Width texels wide
|
||||||
|
// Height
|
||||||
|
// Rescale texture to Height texels high
|
||||||
|
// Depth
|
||||||
|
// Rescale texture to Depth texels deep
|
||||||
|
// FirstMipLevel
|
||||||
|
// First mip level to load
|
||||||
|
// MipLevels
|
||||||
|
// Number of mip levels to load after the first level
|
||||||
|
// Usage
|
||||||
|
// D3D11_USAGE flag for the new texture
|
||||||
|
// BindFlags
|
||||||
|
// D3D11 Bind flags for the new texture
|
||||||
|
// CpuAccessFlags
|
||||||
|
// D3D11 CPU Access flags for the new texture
|
||||||
|
// MiscFlags
|
||||||
|
// Reserved. Must be 0
|
||||||
|
// Format
|
||||||
|
// Resample texture to the specified format
|
||||||
|
// Filter
|
||||||
|
// Filter the texture using the specified filter (only when resampling)
|
||||||
|
// MipFilter
|
||||||
|
// Filter the texture mip levels using the specified filter (only if
|
||||||
|
// generating mips)
|
||||||
|
// pSrcInfo
|
||||||
|
// (optional) pointer to a D3DX11_IMAGE_INFO structure that will get
|
||||||
|
// populated with source image information
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct D3DX11_IMAGE_LOAD_INFO
|
||||||
|
{
|
||||||
|
UINT Width;
|
||||||
|
UINT Height;
|
||||||
|
UINT Depth;
|
||||||
|
UINT FirstMipLevel;
|
||||||
|
UINT MipLevels;
|
||||||
|
D3D11_USAGE Usage;
|
||||||
|
UINT BindFlags;
|
||||||
|
UINT CpuAccessFlags;
|
||||||
|
UINT MiscFlags;
|
||||||
|
DXGI_FORMAT Format;
|
||||||
|
UINT Filter;
|
||||||
|
UINT MipFilter;
|
||||||
|
D3DX11_IMAGE_INFO* pSrcInfo;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
D3DX11_IMAGE_LOAD_INFO()
|
||||||
|
{
|
||||||
|
Width = D3DX11_DEFAULT;
|
||||||
|
Height = D3DX11_DEFAULT;
|
||||||
|
Depth = D3DX11_DEFAULT;
|
||||||
|
FirstMipLevel = D3DX11_DEFAULT;
|
||||||
|
MipLevels = D3DX11_DEFAULT;
|
||||||
|
Usage = (D3D11_USAGE) D3DX11_DEFAULT;
|
||||||
|
BindFlags = D3DX11_DEFAULT;
|
||||||
|
CpuAccessFlags = D3DX11_DEFAULT;
|
||||||
|
MiscFlags = D3DX11_DEFAULT;
|
||||||
|
Format = DXGI_FORMAT_FROM_FILE;
|
||||||
|
Filter = D3DX11_DEFAULT;
|
||||||
|
MipFilter = D3DX11_DEFAULT;
|
||||||
|
pSrcInfo = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} D3DX11_IMAGE_LOAD_INFO;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
// GetImageInfoFromFile/Resource/Memory:
|
||||||
|
// ------------------------------
|
||||||
|
// Fills in a D3DX11_IMAGE_INFO struct with information about an image file.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// pSrcFile
|
||||||
|
// File name of the source image.
|
||||||
|
// pSrcModule
|
||||||
|
// Module where resource is located, or NULL for module associated
|
||||||
|
// with image the os used to create the current process.
|
||||||
|
// pSrcResource
|
||||||
|
// Resource name.
|
||||||
|
// pSrcData
|
||||||
|
// Pointer to file in memory.
|
||||||
|
// SrcDataSize
|
||||||
|
// Size in bytes of file in memory.
|
||||||
|
// pPump
|
||||||
|
// Optional pointer to a thread pump object to use.
|
||||||
|
// pSrcInfo
|
||||||
|
// Pointer to a D3DX11_IMAGE_INFO structure to be filled in with the
|
||||||
|
// description of the data in the source image file.
|
||||||
|
// pHResult
|
||||||
|
// Pointer to a memory location to receive the return value upon completion.
|
||||||
|
// Maybe NULL if not needed.
|
||||||
|
// If pPump != NULL, pHResult must be a valid memory location until the
|
||||||
|
// the asynchronous execution completes.
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11GetImageInfoFromFileA(
|
||||||
|
LPCSTR pSrcFile,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
D3DX11_IMAGE_INFO* pSrcInfo,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11GetImageInfoFromFileW(
|
||||||
|
LPCWSTR pSrcFile,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
D3DX11_IMAGE_INFO* pSrcInfo,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11GetImageInfoFromFile D3DX11GetImageInfoFromFileW
|
||||||
|
#else
|
||||||
|
#define D3DX11GetImageInfoFromFile D3DX11GetImageInfoFromFileA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11GetImageInfoFromResourceA(
|
||||||
|
HMODULE hSrcModule,
|
||||||
|
LPCSTR pSrcResource,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
D3DX11_IMAGE_INFO* pSrcInfo,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11GetImageInfoFromResourceW(
|
||||||
|
HMODULE hSrcModule,
|
||||||
|
LPCWSTR pSrcResource,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
D3DX11_IMAGE_INFO* pSrcInfo,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11GetImageInfoFromResource D3DX11GetImageInfoFromResourceW
|
||||||
|
#else
|
||||||
|
#define D3DX11GetImageInfoFromResource D3DX11GetImageInfoFromResourceA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11GetImageInfoFromMemory(
|
||||||
|
LPCVOID pSrcData,
|
||||||
|
SIZE_T SrcDataSize,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
D3DX11_IMAGE_INFO* pSrcInfo,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Create/Save Texture APIs //////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11CreateTextureFromFile/Resource/Memory:
|
||||||
|
// D3DX11CreateShaderResourceViewFromFile/Resource/Memory:
|
||||||
|
// -----------------------------------
|
||||||
|
// Create a texture object from a file or resource.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
//
|
||||||
|
// pDevice
|
||||||
|
// The D3D device with which the texture is going to be used.
|
||||||
|
// pSrcFile
|
||||||
|
// File name.
|
||||||
|
// hSrcModule
|
||||||
|
// Module handle. if NULL, current module will be used.
|
||||||
|
// pSrcResource
|
||||||
|
// Resource name in module
|
||||||
|
// pvSrcData
|
||||||
|
// Pointer to file in memory.
|
||||||
|
// SrcDataSize
|
||||||
|
// Size in bytes of file in memory.
|
||||||
|
// pLoadInfo
|
||||||
|
// Optional pointer to a D3DX11_IMAGE_LOAD_INFO structure that
|
||||||
|
// contains additional loader parameters.
|
||||||
|
// pPump
|
||||||
|
// Optional pointer to a thread pump object to use.
|
||||||
|
// ppTexture
|
||||||
|
// [out] Created texture object.
|
||||||
|
// ppShaderResourceView
|
||||||
|
// [out] Shader resource view object created.
|
||||||
|
// pHResult
|
||||||
|
// Pointer to a memory location to receive the return value upon completion.
|
||||||
|
// Maybe NULL if not needed.
|
||||||
|
// If pPump != NULL, pHResult must be a valid memory location until the
|
||||||
|
// the asynchronous execution completes.
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// FromFile
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateShaderResourceViewFromFileA(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
LPCSTR pSrcFile,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO *pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11ShaderResourceView** ppShaderResourceView,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateShaderResourceViewFromFileW(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
LPCWSTR pSrcFile,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO *pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11ShaderResourceView** ppShaderResourceView,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11CreateShaderResourceViewFromFile D3DX11CreateShaderResourceViewFromFileW
|
||||||
|
#else
|
||||||
|
#define D3DX11CreateShaderResourceViewFromFile D3DX11CreateShaderResourceViewFromFileA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateTextureFromFileA(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
LPCSTR pSrcFile,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO *pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11Resource** ppTexture,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateTextureFromFileW(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
LPCWSTR pSrcFile,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO *pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11Resource** ppTexture,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11CreateTextureFromFile D3DX11CreateTextureFromFileW
|
||||||
|
#else
|
||||||
|
#define D3DX11CreateTextureFromFile D3DX11CreateTextureFromFileA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// FromResource (resources in dll/exes)
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateShaderResourceViewFromResourceA(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
HMODULE hSrcModule,
|
||||||
|
LPCSTR pSrcResource,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO* pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11ShaderResourceView** ppShaderResourceView,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateShaderResourceViewFromResourceW(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
HMODULE hSrcModule,
|
||||||
|
LPCWSTR pSrcResource,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO* pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11ShaderResourceView** ppShaderResourceView,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11CreateShaderResourceViewFromResource D3DX11CreateShaderResourceViewFromResourceW
|
||||||
|
#else
|
||||||
|
#define D3DX11CreateShaderResourceViewFromResource D3DX11CreateShaderResourceViewFromResourceA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateTextureFromResourceA(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
HMODULE hSrcModule,
|
||||||
|
LPCSTR pSrcResource,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO *pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11Resource** ppTexture,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateTextureFromResourceW(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
HMODULE hSrcModule,
|
||||||
|
LPCWSTR pSrcResource,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO* pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11Resource** ppTexture,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11CreateTextureFromResource D3DX11CreateTextureFromResourceW
|
||||||
|
#else
|
||||||
|
#define D3DX11CreateTextureFromResource D3DX11CreateTextureFromResourceA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// FromFileInMemory
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateShaderResourceViewFromMemory(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
LPCVOID pSrcData,
|
||||||
|
SIZE_T SrcDataSize,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO* pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11ShaderResourceView** ppShaderResourceView,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11CreateTextureFromMemory(
|
||||||
|
ID3D11Device* pDevice,
|
||||||
|
LPCVOID pSrcData,
|
||||||
|
SIZE_T SrcDataSize,
|
||||||
|
D3DX11_IMAGE_LOAD_INFO* pLoadInfo,
|
||||||
|
ID3DX11ThreadPump* pPump,
|
||||||
|
ID3D11Resource** ppTexture,
|
||||||
|
HRESULT* pHResult);
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Misc Texture APIs /////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11_TEXTURE_LOAD_INFO:
|
||||||
|
// ------------------------
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct _D3DX11_TEXTURE_LOAD_INFO
|
||||||
|
{
|
||||||
|
D3D11_BOX *pSrcBox;
|
||||||
|
D3D11_BOX *pDstBox;
|
||||||
|
UINT SrcFirstMip;
|
||||||
|
UINT DstFirstMip;
|
||||||
|
UINT NumMips;
|
||||||
|
UINT SrcFirstElement;
|
||||||
|
UINT DstFirstElement;
|
||||||
|
UINT NumElements;
|
||||||
|
UINT Filter;
|
||||||
|
UINT MipFilter;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
_D3DX11_TEXTURE_LOAD_INFO()
|
||||||
|
{
|
||||||
|
pSrcBox = NULL;
|
||||||
|
pDstBox = NULL;
|
||||||
|
SrcFirstMip = 0;
|
||||||
|
DstFirstMip = 0;
|
||||||
|
NumMips = D3DX11_DEFAULT;
|
||||||
|
SrcFirstElement = 0;
|
||||||
|
DstFirstElement = 0;
|
||||||
|
NumElements = D3DX11_DEFAULT;
|
||||||
|
Filter = D3DX11_DEFAULT;
|
||||||
|
MipFilter = D3DX11_DEFAULT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} D3DX11_TEXTURE_LOAD_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11LoadTextureFromTexture:
|
||||||
|
// ----------------------------
|
||||||
|
// Load a texture from a texture.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11LoadTextureFromTexture(
|
||||||
|
ID3D11DeviceContext *pContext,
|
||||||
|
ID3D11Resource *pSrcTexture,
|
||||||
|
D3DX11_TEXTURE_LOAD_INFO *pLoadInfo,
|
||||||
|
ID3D11Resource *pDstTexture);
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11FilterTexture:
|
||||||
|
// ------------------
|
||||||
|
// Filters mipmaps levels of a texture.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// pBaseTexture
|
||||||
|
// The texture object to be filtered
|
||||||
|
// SrcLevel
|
||||||
|
// The level whose image is used to generate the subsequent levels.
|
||||||
|
// MipFilter
|
||||||
|
// D3DX11_FILTER flags controlling how each miplevel is filtered.
|
||||||
|
// Or D3DX11_DEFAULT for D3DX11_FILTER_BOX,
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11FilterTexture(
|
||||||
|
ID3D11DeviceContext *pContext,
|
||||||
|
ID3D11Resource *pTexture,
|
||||||
|
UINT SrcLevel,
|
||||||
|
UINT MipFilter);
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11SaveTextureToFile:
|
||||||
|
// ----------------------
|
||||||
|
// Save a texture to a file.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// pDestFile
|
||||||
|
// File name of the destination file
|
||||||
|
// DestFormat
|
||||||
|
// D3DX11_IMAGE_FILE_FORMAT specifying file format to use when saving.
|
||||||
|
// pSrcTexture
|
||||||
|
// Source texture, containing the image to be saved
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11SaveTextureToFileA(
|
||||||
|
ID3D11DeviceContext *pContext,
|
||||||
|
ID3D11Resource *pSrcTexture,
|
||||||
|
D3DX11_IMAGE_FILE_FORMAT DestFormat,
|
||||||
|
LPCSTR pDestFile);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11SaveTextureToFileW(
|
||||||
|
ID3D11DeviceContext *pContext,
|
||||||
|
ID3D11Resource *pSrcTexture,
|
||||||
|
D3DX11_IMAGE_FILE_FORMAT DestFormat,
|
||||||
|
LPCWSTR pDestFile);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define D3DX11SaveTextureToFile D3DX11SaveTextureToFileW
|
||||||
|
#else
|
||||||
|
#define D3DX11SaveTextureToFile D3DX11SaveTextureToFileA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11SaveTextureToMemory:
|
||||||
|
// ----------------------
|
||||||
|
// Save a texture to a blob.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// pSrcTexture
|
||||||
|
// Source texture, containing the image to be saved
|
||||||
|
// DestFormat
|
||||||
|
// D3DX11_IMAGE_FILE_FORMAT specifying file format to use when saving.
|
||||||
|
// ppDestBuf
|
||||||
|
// address of a d3dxbuffer pointer to return the image data
|
||||||
|
// Flags
|
||||||
|
// optional flags
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11SaveTextureToMemory(
|
||||||
|
ID3D11DeviceContext *pContext,
|
||||||
|
ID3D11Resource* pSrcTexture,
|
||||||
|
D3DX11_IMAGE_FILE_FORMAT DestFormat,
|
||||||
|
ID3D10Blob** ppDestBuf,
|
||||||
|
UINT Flags);
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11ComputeNormalMap:
|
||||||
|
// ---------------------
|
||||||
|
// Converts a height map into a normal map. The (x,y,z) components of each
|
||||||
|
// normal are mapped to the (r,g,b) channels of the output texture.
|
||||||
|
//
|
||||||
|
// Parameters
|
||||||
|
// pSrcTexture
|
||||||
|
// Pointer to the source heightmap texture
|
||||||
|
// Flags
|
||||||
|
// D3DX11_NORMALMAP flags
|
||||||
|
// Channel
|
||||||
|
// D3DX11_CHANNEL specifying source of height information
|
||||||
|
// Amplitude
|
||||||
|
// The constant value which the height information is multiplied by.
|
||||||
|
// pDestTexture
|
||||||
|
// Pointer to the destination texture
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11ComputeNormalMap(
|
||||||
|
ID3D11DeviceContext *pContext,
|
||||||
|
ID3D11Texture2D *pSrcTexture,
|
||||||
|
UINT Flags,
|
||||||
|
UINT Channel,
|
||||||
|
FLOAT Amplitude,
|
||||||
|
ID3D11Texture2D *pDestTexture);
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// D3DX11SHProjectCubeMap:
|
||||||
|
// ----------------------
|
||||||
|
// Projects a function represented in a cube map into spherical harmonics.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// Order
|
||||||
|
// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1
|
||||||
|
// pCubeMap
|
||||||
|
// CubeMap that is going to be projected into spherical harmonics
|
||||||
|
// pROut
|
||||||
|
// Output SH vector for Red.
|
||||||
|
// pGOut
|
||||||
|
// Output SH vector for Green
|
||||||
|
// pBOut
|
||||||
|
// Output SH vector for Blue
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
D3DX11SHProjectCubeMap(
|
||||||
|
ID3D11DeviceContext *pContext,
|
||||||
|
__in_range(2,6) UINT Order,
|
||||||
|
ID3D11Texture2D *pCubeMap,
|
||||||
|
__out_ecount(Order*Order) FLOAT *pROut,
|
||||||
|
__out_ecount_opt(Order*Order) FLOAT *pGOut,
|
||||||
|
__out_ecount_opt(Order*Order) FLOAT *pBOut);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
#endif //__D3DX11TEX_H__
|
||||||
|
|
190
ScreenRecoder/DXGIDuplicator.cpp
Normal file
190
ScreenRecoder/DXGIDuplicator.cpp
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
#include "DXGIDuplicator.h"
|
||||||
|
#include "Utils/Utils.h"
|
||||||
|
DXGIDuplicator::DXGIDuplicator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGIDuplicator::~DXGIDuplicator()
|
||||||
|
{
|
||||||
|
if (duplication_)
|
||||||
|
{
|
||||||
|
duplication_->Release();
|
||||||
|
}
|
||||||
|
if (device_)
|
||||||
|
{
|
||||||
|
device_->Release();
|
||||||
|
}
|
||||||
|
if (deviceContext_)
|
||||||
|
{
|
||||||
|
deviceContext_->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool DXGIDuplicator::InitD3D11Device(ID3D11Device* g_pd3dDevice, ID3D11DeviceContext* g_pImmediateContext)
|
||||||
|
{
|
||||||
|
device_ = g_pd3dDevice;
|
||||||
|
deviceContext_ = g_pImmediateContext;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool DXGIDuplicator::InitDuplication()
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
IDXGIDevice* dxgiDevice = nullptr;
|
||||||
|
hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDXGIAdapter* dxgiAdapter = nullptr;
|
||||||
|
hr = dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||||
|
dxgiDevice->Release();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT output = 0;
|
||||||
|
IDXGIOutput* dxgiOutput = nullptr;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
hr = dxgiAdapter->EnumOutputs(output++, &dxgiOutput);
|
||||||
|
if (hr == DXGI_ERROR_NOT_FOUND)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DXGI_OUTPUT_DESC desc;
|
||||||
|
dxgiOutput->GetDesc(&desc);
|
||||||
|
Width = desc.DesktopCoordinates.right - desc.DesktopCoordinates.left;
|
||||||
|
Height = desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dxgiAdapter->Release();
|
||||||
|
|
||||||
|
IDXGIOutput1* dxgiOutput1 = nullptr;
|
||||||
|
hr = dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&dxgiOutput1));
|
||||||
|
dxgiOutput->Release();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = dxgiOutput1->DuplicateOutput(device_, &duplication_);
|
||||||
|
dxgiOutput1->Release();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
HRESULT DXGIDuplicator::GetDesktopFrame(ID3D11Texture2D*& texture, UINT TimeoutInMilliseconds)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||||
|
IDXGIResource* resource = NULL;
|
||||||
|
FreeFrame();
|
||||||
|
hr = duplication_->AcquireNextFrame(TimeoutInMilliseconds, &frameInfo, &resource);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
frameRef += 1;
|
||||||
|
hr = resource->QueryInterface(IID_PPV_ARGS(&texture));
|
||||||
|
resource->Release();
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
if (frameInfo.LastPresentTime.QuadPart == 0)
|
||||||
|
return DXGI_ERROR_WAIT_TIMEOUT;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
ID3D11Texture2D* DXGIDuplicator::ConvertFormat(ID3D11Texture2D* pSrcTexture, DXGI_FORMAT fmt)
|
||||||
|
{
|
||||||
|
static ID3D11Texture2D* pDestTexture = NULL;
|
||||||
|
if (pDestTexture == NULL)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
pSrcTexture->GetDesc(&desc);
|
||||||
|
desc.Format = fmt;
|
||||||
|
desc.Usage = D3D11_USAGE_STAGING;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
|
||||||
|
desc.BindFlags = 0;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.SampleDesc.Quality = 0;
|
||||||
|
hr = device_->CreateTexture2D(&desc, NULL, &pDestTexture);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
pDestTexture = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deviceContext_->CopyResource(pDestTexture, pSrcTexture);
|
||||||
|
return pDestTexture;
|
||||||
|
}
|
||||||
|
void* DXGIDuplicator::MapBuffer(ID3D11Texture2D* texture2D)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mappedResource{};
|
||||||
|
hr = this->deviceContext_->Map(texture2D, 0, D3D11_MAP_READ, 0, &mappedResource);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return NULL;
|
||||||
|
return mappedResource.pData;
|
||||||
|
}
|
||||||
|
void DXGIDuplicator::UnMapBuffer(ID3D11Texture2D* texture2D)
|
||||||
|
{
|
||||||
|
this->deviceContext_->Unmap(texture2D, 0);
|
||||||
|
}
|
||||||
|
std::vector<uint8_t> DXGIDuplicator::GenerateBitmapFile(ID3D11Texture2D* texture2D)
|
||||||
|
{
|
||||||
|
D3D11_TEXTURE2D_DESC desc{};
|
||||||
|
texture2D->GetDesc(&desc);
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||||
|
HRESULT hr = this->deviceContext_->Map(texture2D, 0, D3D11_MAP_READ, 0, &mappedResource);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return std::vector<uint8_t>();
|
||||||
|
|
||||||
|
size_t bmpSize = desc.Width * desc.Height * 4;
|
||||||
|
std::vector<uint8_t> result(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmpSize, 0);
|
||||||
|
|
||||||
|
BITMAPFILEHEADER* bmpHeader = (BITMAPFILEHEADER*)(&result[0]);
|
||||||
|
BITMAPINFOHEADER* bmiHeader = (BITMAPINFOHEADER*)(&result[0] + sizeof(BITMAPFILEHEADER));
|
||||||
|
|
||||||
|
uint8_t* rgba = (uint8_t*)(&result[0] + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
|
||||||
|
|
||||||
|
bmpHeader->bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmpSize;
|
||||||
|
bmpHeader->bfType = 0x4D42;
|
||||||
|
bmpHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||||
|
bmpHeader->bfReserved1 = 0;
|
||||||
|
bmpHeader->bfReserved2 = 0;
|
||||||
|
|
||||||
|
bmiHeader->biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
bmiHeader->biWidth = desc.Width;
|
||||||
|
bmiHeader->biHeight = 0 - desc.Height;
|
||||||
|
bmiHeader->biPlanes = 1;
|
||||||
|
bmiHeader->biBitCount = 32;
|
||||||
|
bmiHeader->biCompression = 0;
|
||||||
|
bmiHeader->biSizeImage = bmpSize;
|
||||||
|
bmiHeader->biXPelsPerMeter = 0;
|
||||||
|
bmiHeader->biYPelsPerMeter = 0;
|
||||||
|
bmiHeader->biClrUsed = 0;
|
||||||
|
bmiHeader->biClrImportant = 0;
|
||||||
|
|
||||||
|
memcpy(rgba, mappedResource.pData, bmpSize);
|
||||||
|
this->deviceContext_->Unmap(texture2D, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT DXGIDuplicator::FreeFrame()
|
||||||
|
{
|
||||||
|
if (frameRef > 0)
|
||||||
|
{
|
||||||
|
frameRef -= 1;
|
||||||
|
return duplication_->ReleaseFrame();
|
||||||
|
}
|
||||||
|
return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
|
||||||
|
}
|
32
ScreenRecoder/DXGIDuplicator.h
Normal file
32
ScreenRecoder/DXGIDuplicator.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <dxgi1_2.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#pragma comment(lib, "d3d11.lib")
|
||||||
|
#pragma comment(lib, "dxgi.lib")
|
||||||
|
|
||||||
|
|
||||||
|
class DXGIDuplicator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int Width;
|
||||||
|
int Height;
|
||||||
|
DXGIDuplicator();
|
||||||
|
~DXGIDuplicator();
|
||||||
|
bool InitD3D11Device(ID3D11Device* g_pd3dDevice,ID3D11DeviceContext* g_pImmediateContext);
|
||||||
|
bool InitDuplication();
|
||||||
|
HRESULT GetDesktopFrame(ID3D11Texture2D*& texture, UINT TimeoutInMilliseconds = 0);
|
||||||
|
ID3D11Texture2D* ConvertFormat(ID3D11Texture2D* pSrcTexture, DXGI_FORMAT fmt = DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
std::vector<uint8_t> GenerateBitmapFile(ID3D11Texture2D* texture2D);
|
||||||
|
|
||||||
|
void* MapBuffer(ID3D11Texture2D* texture2D);
|
||||||
|
void UnMapBuffer(ID3D11Texture2D* texture2D);
|
||||||
|
HRESULT FreeFrame();
|
||||||
|
private:
|
||||||
|
int frameRef = 0;
|
||||||
|
ID3D11Device* device_ = nullptr;
|
||||||
|
ID3D11DeviceContext* deviceContext_ = nullptr;
|
||||||
|
IDXGIOutputDuplication* duplication_ = nullptr;
|
||||||
|
};
|
||||||
|
|
BIN
ScreenRecoder/Delogo.ico
Normal file
BIN
ScreenRecoder/Delogo.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
136
ScreenRecoder/ImGui/imconfig.h
Normal file
136
ScreenRecoder/ImGui/imconfig.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// DEAR IMGUI COMPILE-TIME OPTIONS
|
||||||
|
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||||
|
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 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)
|
||||||
|
// 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.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||||
|
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||||
|
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||||
|
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//---- Define assertion handler. Defaults to calling assert().
|
||||||
|
// 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.
|
||||||
|
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||||
|
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||||
|
|
||||||
|
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||||
|
// 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.
|
||||||
|
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||||
|
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||||
|
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export
|
||||||
|
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
|
||||||
|
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
|
||||||
|
|
||||||
|
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||||
|
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS.
|
||||||
|
|
||||||
|
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||||
|
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||||
|
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||||
|
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
||||||
|
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
|
||||||
|
|
||||||
|
//---- Don't implement some functions to reduce linkage requirements.
|
||||||
|
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||||
|
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||||
|
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||||
|
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||||
|
//#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).
|
||||||
|
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default io.PlatformOpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||||
|
//#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)
|
||||||
|
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||||
|
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||||
|
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle 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.
|
||||||
|
//#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().
|
||||||
|
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||||
|
|
||||||
|
//---- Enable Test Engine / Automation features.
|
||||||
|
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
|
||||||
|
|
||||||
|
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||||
|
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||||
|
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||||
|
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||||
|
|
||||||
|
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||||
|
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
|
||||||
|
//---- 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...)
|
||||||
|
//#define IMGUI_USE_WCHAR32
|
||||||
|
|
||||||
|
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||||
|
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||||
|
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||||
|
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||||
|
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||||
|
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
||||||
|
|
||||||
|
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||||
|
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||||
|
//#define IMGUI_USE_STB_SPRINTF
|
||||||
|
|
||||||
|
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||||
|
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||||
|
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||||
|
//#define IMGUI_ENABLE_FREETYPE
|
||||||
|
|
||||||
|
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
|
||||||
|
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
|
||||||
|
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||||
|
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||||
|
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||||
|
|
||||||
|
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||||
|
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||||
|
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||||
|
|
||||||
|
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||||
|
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||||
|
/*
|
||||||
|
#define IM_VEC2_CLASS_EXTRA \
|
||||||
|
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||||
|
operator MyVec2() const { return MyVec2(x,y); }
|
||||||
|
|
||||||
|
#define IM_VEC4_CLASS_EXTRA \
|
||||||
|
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||||
|
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||||
|
*/
|
||||||
|
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||||
|
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
|
||||||
|
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||||
|
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||||
|
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||||
|
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||||
|
//#define ImDrawIdx unsigned int
|
||||||
|
|
||||||
|
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||||
|
//struct ImDrawList;
|
||||||
|
//struct ImDrawCmd;
|
||||||
|
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||||
|
//#define ImDrawCallback MyImDrawCallback
|
||||||
|
|
||||||
|
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
||||||
|
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||||
|
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||||
|
//#define IM_DEBUG_BREAK __debugbreak()
|
||||||
|
|
||||||
|
//---- Debug Tools: Enable slower asserts
|
||||||
|
//#define IMGUI_DEBUG_PARANOID
|
||||||
|
|
||||||
|
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||||
|
/*
|
||||||
|
namespace ImGui
|
||||||
|
{
|
||||||
|
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||||
|
}
|
||||||
|
*/
|
16263
ScreenRecoder/ImGui/imgui.cpp
Normal file
16263
ScreenRecoder/ImGui/imgui.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3643
ScreenRecoder/ImGui/imgui.h
Normal file
3643
ScreenRecoder/ImGui/imgui.h
Normal file
File diff suppressed because it is too large
Load Diff
10316
ScreenRecoder/ImGui/imgui_demo.cpp
Normal file
10316
ScreenRecoder/ImGui/imgui_demo.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4634
ScreenRecoder/ImGui/imgui_draw.cpp
Normal file
4634
ScreenRecoder/ImGui/imgui_draw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
590
ScreenRecoder/ImGui/imgui_impl_dx10.cpp
Normal file
590
ScreenRecoder/ImGui/imgui_impl_dx10.cpp
Normal file
@ -0,0 +1,590 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX10
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
// CHANGELOG
|
||||||
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
|
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||||
|
// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
|
// 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer.
|
||||||
|
// 2019-07-21: DirectX10: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData().
|
||||||
|
// 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||||
|
// 2019-04-30: DirectX10: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||||
|
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
||||||
|
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||||
|
// 2018-07-13: DirectX10: Fixed unreleased resources in Init and Shutdown functions.
|
||||||
|
// 2018-06-08: Misc: Extracted imgui_impl_dx10.cpp/.h away from the old combined DX10+Win32 example.
|
||||||
|
// 2018-06-08: DirectX10: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||||
|
// 2018-04-09: Misc: Fixed erroneous call to io.Fonts->ClearInputData() + ClearTexData() that was left in DX10 example but removed in 1.47 (Nov 2015) on other backends.
|
||||||
|
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX10_RenderDrawData() in the .h file so you can call it yourself.
|
||||||
|
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||||
|
// 2016-05-07: DirectX10: Disabling depth-write.
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui_impl_dx10.h"
|
||||||
|
|
||||||
|
// DirectX
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <d3d10_1.h>
|
||||||
|
#include <d3d10.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// DirectX data
|
||||||
|
struct ImGui_ImplDX10_Data
|
||||||
|
{
|
||||||
|
ID3D10Device* pd3dDevice;
|
||||||
|
IDXGIFactory* pFactory;
|
||||||
|
ID3D10Buffer* pVB;
|
||||||
|
ID3D10Buffer* pIB;
|
||||||
|
ID3D10VertexShader* pVertexShader;
|
||||||
|
ID3D10InputLayout* pInputLayout;
|
||||||
|
ID3D10Buffer* pVertexConstantBuffer;
|
||||||
|
ID3D10PixelShader* pPixelShader;
|
||||||
|
ID3D10SamplerState* pFontSampler;
|
||||||
|
ID3D10ShaderResourceView* pFontTextureView;
|
||||||
|
ID3D10RasterizerState* pRasterizerState;
|
||||||
|
ID3D10BlendState* pBlendState;
|
||||||
|
ID3D10DepthStencilState* pDepthStencilState;
|
||||||
|
int VertexBufferSize;
|
||||||
|
int IndexBufferSize;
|
||||||
|
|
||||||
|
ImGui_ImplDX10_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VERTEX_CONSTANT_BUFFER_DX10
|
||||||
|
{
|
||||||
|
float mvp[4][4];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||||
|
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||||
|
static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
|
||||||
|
// Setup viewport
|
||||||
|
D3D10_VIEWPORT vp;
|
||||||
|
memset(&vp, 0, sizeof(D3D10_VIEWPORT));
|
||||||
|
vp.Width = (UINT)draw_data->DisplaySize.x;
|
||||||
|
vp.Height = (UINT)draw_data->DisplaySize.y;
|
||||||
|
vp.MinDepth = 0.0f;
|
||||||
|
vp.MaxDepth = 1.0f;
|
||||||
|
vp.TopLeftX = vp.TopLeftY = 0;
|
||||||
|
ctx->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
|
// Bind shader and vertex buffers
|
||||||
|
unsigned int stride = sizeof(ImDrawVert);
|
||||||
|
unsigned int offset = 0;
|
||||||
|
ctx->IASetInputLayout(bd->pInputLayout);
|
||||||
|
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||||
|
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
ctx->VSSetShader(bd->pVertexShader);
|
||||||
|
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||||
|
ctx->PSSetShader(bd->pPixelShader);
|
||||||
|
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||||
|
ctx->GSSetShader(nullptr);
|
||||||
|
|
||||||
|
// Setup render state
|
||||||
|
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
|
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||||
|
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||||
|
ctx->RSSetState(bd->pRasterizerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render function
|
||||||
|
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized
|
||||||
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
ID3D10Device* ctx = bd->pd3dDevice;
|
||||||
|
|
||||||
|
// Create and grow vertex/index buffers if needed
|
||||||
|
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
|
{
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
|
D3D10_BUFFER_DESC desc;
|
||||||
|
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||||
|
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||||
|
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
if (ctx->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
|
{
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
|
D3D10_BUFFER_DESC desc;
|
||||||
|
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||||
|
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
|
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||||
|
if (ctx->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy and convert all vertices into a single contiguous buffer
|
||||||
|
ImDrawVert* vtx_dst = nullptr;
|
||||||
|
ImDrawIdx* idx_dst = nullptr;
|
||||||
|
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
||||||
|
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||||
|
idx_dst += cmd_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
bd->pVB->Unmap();
|
||||||
|
bd->pIB->Unmap();
|
||||||
|
|
||||||
|
// Setup orthographic projection matrix into our constant buffer
|
||||||
|
// 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.
|
||||||
|
{
|
||||||
|
void* mapped_resource;
|
||||||
|
if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
VERTEX_CONSTANT_BUFFER_DX10* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX10*)mapped_resource;
|
||||||
|
float L = draw_data->DisplayPos.x;
|
||||||
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
|
float T = draw_data->DisplayPos.y;
|
||||||
|
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||||
|
float mvp[4][4] =
|
||||||
|
{
|
||||||
|
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||||
|
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||||
|
};
|
||||||
|
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||||
|
bd->pVertexConstantBuffer->Unmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||||
|
struct BACKUP_DX10_STATE
|
||||||
|
{
|
||||||
|
UINT ScissorRectsCount, ViewportsCount;
|
||||||
|
D3D10_RECT ScissorRects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||||
|
D3D10_VIEWPORT Viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||||
|
ID3D10RasterizerState* RS;
|
||||||
|
ID3D10BlendState* BlendState;
|
||||||
|
FLOAT BlendFactor[4];
|
||||||
|
UINT SampleMask;
|
||||||
|
UINT StencilRef;
|
||||||
|
ID3D10DepthStencilState* DepthStencilState;
|
||||||
|
ID3D10ShaderResourceView* PSShaderResource;
|
||||||
|
ID3D10SamplerState* PSSampler;
|
||||||
|
ID3D10PixelShader* PS;
|
||||||
|
ID3D10VertexShader* VS;
|
||||||
|
ID3D10GeometryShader* GS;
|
||||||
|
D3D10_PRIMITIVE_TOPOLOGY PrimitiveTopology;
|
||||||
|
ID3D10Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
|
||||||
|
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
|
||||||
|
DXGI_FORMAT IndexBufferFormat;
|
||||||
|
ID3D10InputLayout* InputLayout;
|
||||||
|
};
|
||||||
|
BACKUP_DX10_STATE old = {};
|
||||||
|
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||||
|
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||||
|
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||||
|
ctx->RSGetState(&old.RS);
|
||||||
|
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||||
|
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||||
|
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||||
|
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
||||||
|
ctx->PSGetShader(&old.PS);
|
||||||
|
ctx->VSGetShader(&old.VS);
|
||||||
|
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||||
|
ctx->GSGetShader(&old.GS);
|
||||||
|
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||||
|
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||||
|
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||||
|
ctx->IAGetInputLayout(&old.InputLayout);
|
||||||
|
|
||||||
|
// Setup desired DX state
|
||||||
|
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
|
||||||
|
|
||||||
|
// Render command lists
|
||||||
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
|
int global_vtx_offset = 0;
|
||||||
|
int global_idx_offset = 0;
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||||
|
if (pcmd->UserCallback)
|
||||||
|
{
|
||||||
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
|
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
|
||||||
|
else
|
||||||
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply scissor/clipping rectangle
|
||||||
|
const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
|
ctx->RSSetScissorRects(1, &r);
|
||||||
|
|
||||||
|
// Bind texture, Draw
|
||||||
|
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID();
|
||||||
|
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||||
|
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||||
|
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore modified DX state
|
||||||
|
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||||
|
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||||
|
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||||
|
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||||
|
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||||
|
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||||
|
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||||
|
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
|
||||||
|
ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release();
|
||||||
|
ctx->GSSetShader(old.GS); if (old.GS) old.GS->Release();
|
||||||
|
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||||
|
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||||
|
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||||
|
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||||
|
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX10_CreateFontsTexture()
|
||||||
|
{
|
||||||
|
// Build texture atlas
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
unsigned char* pixels;
|
||||||
|
int width, height;
|
||||||
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||||
|
|
||||||
|
// Upload texture to graphics system
|
||||||
|
{
|
||||||
|
D3D10_TEXTURE2D_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Width = width;
|
||||||
|
desc.Height = height;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Usage = D3D10_USAGE_DEFAULT;
|
||||||
|
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
|
||||||
|
ID3D10Texture2D* pTexture = nullptr;
|
||||||
|
D3D10_SUBRESOURCE_DATA subResource;
|
||||||
|
subResource.pSysMem = pixels;
|
||||||
|
subResource.SysMemPitch = desc.Width * 4;
|
||||||
|
subResource.SysMemSlicePitch = 0;
|
||||||
|
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||||
|
IM_ASSERT(pTexture != nullptr);
|
||||||
|
|
||||||
|
// Create texture view
|
||||||
|
D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||||
|
ZeroMemory(&srv_desc, sizeof(srv_desc));
|
||||||
|
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srv_desc.Texture2D.MipLevels = desc.MipLevels;
|
||||||
|
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||||
|
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srv_desc, &bd->pFontTextureView);
|
||||||
|
pTexture->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store our identifier
|
||||||
|
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||||
|
|
||||||
|
// Create texture sampler
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
|
{
|
||||||
|
D3D10_SAMPLER_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||||
|
desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||||
|
desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||||
|
desc.MipLODBias = 0.f;
|
||||||
|
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
|
||||||
|
desc.MinLOD = 0.f;
|
||||||
|
desc.MaxLOD = 0.f;
|
||||||
|
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX10_CreateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
if (!bd->pd3dDevice)
|
||||||
|
return false;
|
||||||
|
if (bd->pFontSampler)
|
||||||
|
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||||
|
// If you would like to use this DX10 sample code but remove this dependency you can:
|
||||||
|
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
|
||||||
|
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||||
|
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||||
|
|
||||||
|
// Create the vertex shader
|
||||||
|
{
|
||||||
|
static const char* vertexShader =
|
||||||
|
"cbuffer vertexBuffer : register(b0) \
|
||||||
|
{\
|
||||||
|
float4x4 ProjectionMatrix; \
|
||||||
|
};\
|
||||||
|
struct VS_INPUT\
|
||||||
|
{\
|
||||||
|
float2 pos : POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
\
|
||||||
|
struct PS_INPUT\
|
||||||
|
{\
|
||||||
|
float4 pos : SV_POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
\
|
||||||
|
PS_INPUT main(VS_INPUT input)\
|
||||||
|
{\
|
||||||
|
PS_INPUT output;\
|
||||||
|
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
|
||||||
|
output.col = input.col;\
|
||||||
|
output.uv = input.uv;\
|
||||||
|
return output;\
|
||||||
|
}";
|
||||||
|
|
||||||
|
ID3DBlob* vertexShaderBlob;
|
||||||
|
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||||
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
|
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pVertexShader) != S_OK)
|
||||||
|
{
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the input layout
|
||||||
|
D3D10_INPUT_ELEMENT_DESC local_layout[] =
|
||||||
|
{
|
||||||
|
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
};
|
||||||
|
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
||||||
|
{
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
|
||||||
|
// Create the constant buffer
|
||||||
|
{
|
||||||
|
D3D10_BUFFER_DESC desc;
|
||||||
|
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX10);
|
||||||
|
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||||
|
desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the pixel shader
|
||||||
|
{
|
||||||
|
static const char* pixelShader =
|
||||||
|
"struct PS_INPUT\
|
||||||
|
{\
|
||||||
|
float4 pos : SV_POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
sampler sampler0;\
|
||||||
|
Texture2D texture0;\
|
||||||
|
\
|
||||||
|
float4 main(PS_INPUT input) : SV_Target\
|
||||||
|
{\
|
||||||
|
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||||
|
return out_col; \
|
||||||
|
}";
|
||||||
|
|
||||||
|
ID3DBlob* pixelShaderBlob;
|
||||||
|
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||||
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
|
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), &bd->pPixelShader) != S_OK)
|
||||||
|
{
|
||||||
|
pixelShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pixelShaderBlob->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the blending setup
|
||||||
|
{
|
||||||
|
D3D10_BLEND_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.AlphaToCoverageEnable = false;
|
||||||
|
desc.BlendEnable[0] = true;
|
||||||
|
desc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
|
||||||
|
desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
|
||||||
|
desc.BlendOp = D3D10_BLEND_OP_ADD;
|
||||||
|
desc.SrcBlendAlpha = D3D10_BLEND_ONE;
|
||||||
|
desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
|
||||||
|
desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
|
||||||
|
desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
|
||||||
|
bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the rasterizer state
|
||||||
|
{
|
||||||
|
D3D10_RASTERIZER_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.FillMode = D3D10_FILL_SOLID;
|
||||||
|
desc.CullMode = D3D10_CULL_NONE;
|
||||||
|
desc.ScissorEnable = true;
|
||||||
|
desc.DepthClipEnable = true;
|
||||||
|
bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create depth-stencil State
|
||||||
|
{
|
||||||
|
D3D10_DEPTH_STENCIL_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.DepthEnable = false;
|
||||||
|
desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
|
||||||
|
desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
|
||||||
|
desc.StencilEnable = false;
|
||||||
|
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
|
||||||
|
desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
|
||||||
|
desc.BackFace = desc.FrontFace;
|
||||||
|
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui_ImplDX10_CreateFontsTexture();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX10_InvalidateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
if (!bd->pd3dDevice)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||||
|
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||||
|
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
|
||||||
|
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
|
||||||
|
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
|
||||||
|
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
|
||||||
|
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
|
||||||
|
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
|
|
||||||
|
// Setup backend capabilities flags
|
||||||
|
ImGui_ImplDX10_Data* bd = IM_NEW(ImGui_ImplDX10_Data)();
|
||||||
|
io.BackendRendererUserData = (void*)bd;
|
||||||
|
io.BackendRendererName = "imgui_impl_dx10";
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
|
|
||||||
|
// Get factory from device
|
||||||
|
IDXGIDevice* pDXGIDevice = nullptr;
|
||||||
|
IDXGIAdapter* pDXGIAdapter = nullptr;
|
||||||
|
IDXGIFactory* pFactory = nullptr;
|
||||||
|
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
||||||
|
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
||||||
|
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
|
||||||
|
{
|
||||||
|
bd->pd3dDevice = device;
|
||||||
|
bd->pFactory = pFactory;
|
||||||
|
}
|
||||||
|
if (pDXGIDevice) pDXGIDevice->Release();
|
||||||
|
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||||
|
bd->pd3dDevice->AddRef();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX10_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||||
|
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||||
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
|
io.BackendRendererName = nullptr;
|
||||||
|
io.BackendRendererUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX10_NewFrame()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX10_Init()?");
|
||||||
|
|
||||||
|
if (!bd->pFontSampler)
|
||||||
|
ImGui_ImplDX10_CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
32
ScreenRecoder/ImGui/imgui_impl_dx10.h
Normal file
32
ScreenRecoder/ImGui/imgui_impl_dx10.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX10
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
struct ID3D10Device;
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX10_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX10_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
606
ScreenRecoder/ImGui/imgui_impl_dx11.cpp
Normal file
606
ScreenRecoder/ImGui/imgui_impl_dx11.cpp
Normal file
@ -0,0 +1,606 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX11
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
// CHANGELOG
|
||||||
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
|
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||||
|
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
|
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||||
|
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
|
||||||
|
// 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.
|
||||||
|
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||||
|
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||||
|
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
||||||
|
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||||
|
// 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility.
|
||||||
|
// 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions.
|
||||||
|
// 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example.
|
||||||
|
// 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||||
|
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself.
|
||||||
|
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||||
|
// 2016-05-07: DirectX11: Disabling depth-write.
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui_impl_dx11.h"
|
||||||
|
|
||||||
|
// DirectX
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// DirectX11 data
|
||||||
|
struct ImGui_ImplDX11_Data
|
||||||
|
{
|
||||||
|
ID3D11Device* pd3dDevice;
|
||||||
|
ID3D11DeviceContext* pd3dDeviceContext;
|
||||||
|
IDXGIFactory* pFactory;
|
||||||
|
ID3D11Buffer* pVB;
|
||||||
|
ID3D11Buffer* pIB;
|
||||||
|
ID3D11VertexShader* pVertexShader;
|
||||||
|
ID3D11InputLayout* pInputLayout;
|
||||||
|
ID3D11Buffer* pVertexConstantBuffer;
|
||||||
|
ID3D11PixelShader* pPixelShader;
|
||||||
|
ID3D11SamplerState* pFontSampler;
|
||||||
|
ID3D11ShaderResourceView* pFontTextureView;
|
||||||
|
ID3D11RasterizerState* pRasterizerState;
|
||||||
|
ID3D11BlendState* pBlendState;
|
||||||
|
ID3D11DepthStencilState* pDepthStencilState;
|
||||||
|
int VertexBufferSize;
|
||||||
|
int IndexBufferSize;
|
||||||
|
|
||||||
|
ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VERTEX_CONSTANT_BUFFER_DX11
|
||||||
|
{
|
||||||
|
float mvp[4][4];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||||
|
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||||
|
static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
|
||||||
|
// Setup viewport
|
||||||
|
D3D11_VIEWPORT vp;
|
||||||
|
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
|
||||||
|
vp.Width = draw_data->DisplaySize.x;
|
||||||
|
vp.Height = draw_data->DisplaySize.y;
|
||||||
|
vp.MinDepth = 0.0f;
|
||||||
|
vp.MaxDepth = 1.0f;
|
||||||
|
vp.TopLeftX = vp.TopLeftY = 0;
|
||||||
|
ctx->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
|
// Setup shader and vertex buffers
|
||||||
|
unsigned int stride = sizeof(ImDrawVert);
|
||||||
|
unsigned int offset = 0;
|
||||||
|
ctx->IASetInputLayout(bd->pInputLayout);
|
||||||
|
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||||
|
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||||
|
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||||
|
ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||||
|
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||||
|
ctx->GSSetShader(nullptr, nullptr, 0);
|
||||||
|
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
|
||||||
|
// Setup blend state
|
||||||
|
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
|
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||||
|
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||||
|
ctx->RSSetState(bd->pRasterizerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render function
|
||||||
|
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized
|
||||||
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
ID3D11DeviceContext* ctx = bd->pd3dDeviceContext;
|
||||||
|
|
||||||
|
// Create and grow vertex/index buffers if needed
|
||||||
|
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
|
{
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
|
D3D11_BUFFER_DESC desc;
|
||||||
|
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||||
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||||
|
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
|
{
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
|
D3D11_BUFFER_DESC desc;
|
||||||
|
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||||
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
|
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload vertex/index data into a single contiguous GPU buffer
|
||||||
|
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
||||||
|
if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||||
|
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||||
|
idx_dst += cmd_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
ctx->Unmap(bd->pVB, 0);
|
||||||
|
ctx->Unmap(bd->pIB, 0);
|
||||||
|
|
||||||
|
// Setup orthographic projection matrix into our constant buffer
|
||||||
|
// 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.
|
||||||
|
{
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||||
|
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||||
|
float L = draw_data->DisplayPos.x;
|
||||||
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
|
float T = draw_data->DisplayPos.y;
|
||||||
|
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||||
|
float mvp[4][4] =
|
||||||
|
{
|
||||||
|
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||||
|
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||||
|
};
|
||||||
|
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||||
|
ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||||
|
struct BACKUP_DX11_STATE
|
||||||
|
{
|
||||||
|
UINT ScissorRectsCount, ViewportsCount;
|
||||||
|
D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||||
|
D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||||
|
ID3D11RasterizerState* RS;
|
||||||
|
ID3D11BlendState* BlendState;
|
||||||
|
FLOAT BlendFactor[4];
|
||||||
|
UINT SampleMask;
|
||||||
|
UINT StencilRef;
|
||||||
|
ID3D11DepthStencilState* DepthStencilState;
|
||||||
|
ID3D11ShaderResourceView* PSShaderResource;
|
||||||
|
ID3D11SamplerState* PSSampler;
|
||||||
|
ID3D11PixelShader* PS;
|
||||||
|
ID3D11VertexShader* VS;
|
||||||
|
ID3D11GeometryShader* GS;
|
||||||
|
UINT PSInstancesCount, VSInstancesCount, GSInstancesCount;
|
||||||
|
ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
|
||||||
|
ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
|
||||||
|
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
|
||||||
|
DXGI_FORMAT IndexBufferFormat;
|
||||||
|
ID3D11InputLayout* InputLayout;
|
||||||
|
};
|
||||||
|
BACKUP_DX11_STATE old = {};
|
||||||
|
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||||
|
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||||
|
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||||
|
ctx->RSGetState(&old.RS);
|
||||||
|
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||||
|
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||||
|
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||||
|
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
||||||
|
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
|
||||||
|
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||||
|
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||||
|
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||||
|
ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
||||||
|
|
||||||
|
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||||
|
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||||
|
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||||
|
ctx->IAGetInputLayout(&old.InputLayout);
|
||||||
|
|
||||||
|
// Setup desired DX state
|
||||||
|
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
||||||
|
|
||||||
|
// Render command lists
|
||||||
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
|
int global_idx_offset = 0;
|
||||||
|
int global_vtx_offset = 0;
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||||
|
if (pcmd->UserCallback != nullptr)
|
||||||
|
{
|
||||||
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
|
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
||||||
|
else
|
||||||
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply scissor/clipping rectangle
|
||||||
|
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
|
ctx->RSSetScissorRects(1, &r);
|
||||||
|
|
||||||
|
// Bind texture, Draw
|
||||||
|
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
|
||||||
|
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||||
|
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||||
|
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore modified DX state
|
||||||
|
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||||
|
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||||
|
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||||
|
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||||
|
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||||
|
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||||
|
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||||
|
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||||
|
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
|
||||||
|
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||||
|
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||||
|
ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
||||||
|
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
|
||||||
|
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||||
|
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||||
|
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||||
|
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_CreateFontsTexture()
|
||||||
|
{
|
||||||
|
// Build texture atlas
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
unsigned char* pixels;
|
||||||
|
int width, height;
|
||||||
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||||
|
|
||||||
|
// Upload texture to graphics system
|
||||||
|
{
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Width = width;
|
||||||
|
desc.Height = height;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
|
||||||
|
ID3D11Texture2D* pTexture = nullptr;
|
||||||
|
D3D11_SUBRESOURCE_DATA subResource;
|
||||||
|
subResource.pSysMem = pixels;
|
||||||
|
subResource.SysMemPitch = desc.Width * 4;
|
||||||
|
subResource.SysMemSlicePitch = 0;
|
||||||
|
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||||
|
IM_ASSERT(pTexture != nullptr);
|
||||||
|
|
||||||
|
// Create texture view
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||||
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||||
|
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView);
|
||||||
|
pTexture->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store our identifier
|
||||||
|
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||||
|
|
||||||
|
// Create texture sampler
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
|
{
|
||||||
|
D3D11_SAMPLER_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
desc.MipLODBias = 0.f;
|
||||||
|
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.MinLOD = 0.f;
|
||||||
|
desc.MaxLOD = 0.f;
|
||||||
|
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
if (!bd->pd3dDevice)
|
||||||
|
return false;
|
||||||
|
if (bd->pFontSampler)
|
||||||
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||||
|
// If you would like to use this DX11 sample code but remove this dependency you can:
|
||||||
|
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
|
||||||
|
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||||
|
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||||
|
|
||||||
|
// Create the vertex shader
|
||||||
|
{
|
||||||
|
static const char* vertexShader =
|
||||||
|
"cbuffer vertexBuffer : register(b0) \
|
||||||
|
{\
|
||||||
|
float4x4 ProjectionMatrix; \
|
||||||
|
};\
|
||||||
|
struct VS_INPUT\
|
||||||
|
{\
|
||||||
|
float2 pos : POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
\
|
||||||
|
struct PS_INPUT\
|
||||||
|
{\
|
||||||
|
float4 pos : SV_POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
\
|
||||||
|
PS_INPUT main(VS_INPUT input)\
|
||||||
|
{\
|
||||||
|
PS_INPUT output;\
|
||||||
|
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
|
||||||
|
output.col = input.col;\
|
||||||
|
output.uv = input.uv;\
|
||||||
|
return output;\
|
||||||
|
}";
|
||||||
|
|
||||||
|
ID3DBlob* vertexShaderBlob;
|
||||||
|
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||||
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
|
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
|
||||||
|
{
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the input layout
|
||||||
|
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
||||||
|
{
|
||||||
|
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
};
|
||||||
|
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
||||||
|
{
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
|
||||||
|
// Create the constant buffer
|
||||||
|
{
|
||||||
|
D3D11_BUFFER_DESC desc;
|
||||||
|
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
|
||||||
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the pixel shader
|
||||||
|
{
|
||||||
|
static const char* pixelShader =
|
||||||
|
"struct PS_INPUT\
|
||||||
|
{\
|
||||||
|
float4 pos : SV_POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
sampler sampler0;\
|
||||||
|
Texture2D texture0;\
|
||||||
|
\
|
||||||
|
float4 main(PS_INPUT input) : SV_Target\
|
||||||
|
{\
|
||||||
|
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||||
|
return out_col; \
|
||||||
|
}";
|
||||||
|
|
||||||
|
ID3DBlob* pixelShaderBlob;
|
||||||
|
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||||
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
|
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
|
||||||
|
{
|
||||||
|
pixelShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pixelShaderBlob->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the blending setup
|
||||||
|
{
|
||||||
|
D3D11_BLEND_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.AlphaToCoverageEnable = false;
|
||||||
|
desc.RenderTarget[0].BlendEnable = true;
|
||||||
|
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||||
|
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||||
|
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||||
|
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||||
|
bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the rasterizer state
|
||||||
|
{
|
||||||
|
D3D11_RASTERIZER_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.FillMode = D3D11_FILL_SOLID;
|
||||||
|
desc.CullMode = D3D11_CULL_NONE;
|
||||||
|
desc.ScissorEnable = true;
|
||||||
|
desc.DepthClipEnable = true;
|
||||||
|
bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create depth-stencil State
|
||||||
|
{
|
||||||
|
D3D11_DEPTH_STENCIL_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.DepthEnable = false;
|
||||||
|
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||||
|
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.StencilEnable = false;
|
||||||
|
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.BackFace = desc.FrontFace;
|
||||||
|
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui_ImplDX11_CreateFontsTexture();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
if (!bd->pd3dDevice)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||||
|
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||||
|
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
|
||||||
|
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
|
||||||
|
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
|
||||||
|
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
|
||||||
|
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
|
||||||
|
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
|
|
||||||
|
// Setup backend capabilities flags
|
||||||
|
ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
|
||||||
|
io.BackendRendererUserData = (void*)bd;
|
||||||
|
io.BackendRendererName = "imgui_impl_dx11";
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
|
|
||||||
|
// Get factory from device
|
||||||
|
IDXGIDevice* pDXGIDevice = nullptr;
|
||||||
|
IDXGIAdapter* pDXGIAdapter = nullptr;
|
||||||
|
IDXGIFactory* pFactory = nullptr;
|
||||||
|
|
||||||
|
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
||||||
|
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
||||||
|
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
|
||||||
|
{
|
||||||
|
bd->pd3dDevice = device;
|
||||||
|
bd->pd3dDeviceContext = device_context;
|
||||||
|
bd->pFactory = pFactory;
|
||||||
|
}
|
||||||
|
if (pDXGIDevice) pDXGIDevice->Release();
|
||||||
|
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||||
|
bd->pd3dDevice->AddRef();
|
||||||
|
bd->pd3dDeviceContext->AddRef();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX11_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
|
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||||
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
|
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||||
|
io.BackendRendererName = nullptr;
|
||||||
|
io.BackendRendererUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX11_NewFrame()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX11_Init()?");
|
||||||
|
|
||||||
|
if (!bd->pFontSampler)
|
||||||
|
ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
33
ScreenRecoder/ImGui/imgui_impl_dx11.h
Normal file
33
ScreenRecoder/ImGui/imgui_impl_dx11.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX11
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
struct ID3D11Device;
|
||||||
|
struct ID3D11DeviceContext;
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
762
ScreenRecoder/ImGui/imgui_impl_dx12.cpp
Normal file
762
ScreenRecoder/ImGui/imgui_impl_dx12.cpp
Normal file
@ -0,0 +1,762 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX12
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
|
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||||
|
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||||
|
// To build this on 32-bit systems:
|
||||||
|
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
|
||||||
|
// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
||||||
|
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
||||||
|
// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
// CHANGELOG
|
||||||
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
|
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||||
|
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
|
// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer.
|
||||||
|
// 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically.
|
||||||
|
// 2020-09-16: DirectX12: Avoid rendering calls with zero-sized scissor rectangle since it generates a validation layer warning.
|
||||||
|
// 2020-09-08: DirectX12: Clarified support for building on 32-bit systems by redefining ImTextureID.
|
||||||
|
// 2019-10-18: DirectX12: *BREAKING CHANGE* Added extra ID3D12DescriptorHeap parameter to ImGui_ImplDX12_Init() function.
|
||||||
|
// 2019-05-29: DirectX12: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||||
|
// 2019-04-30: DirectX12: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||||
|
// 2019-03-29: Misc: Various minor tidying up.
|
||||||
|
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
||||||
|
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||||
|
// 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData().
|
||||||
|
// 2018-06-08: Misc: Extracted imgui_impl_dx12.cpp/.h away from the old combined DX12+Win32 example.
|
||||||
|
// 2018-06-08: DirectX12: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle (to ease support for future multi-viewport).
|
||||||
|
// 2018-02-22: Merged into master with all Win32 code synchronized to other examples.
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui_impl_dx12.h"
|
||||||
|
|
||||||
|
// DirectX
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <dxgi1_4.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// DirectX data
|
||||||
|
struct ImGui_ImplDX12_RenderBuffers;
|
||||||
|
struct ImGui_ImplDX12_Data
|
||||||
|
{
|
||||||
|
ID3D12Device* pd3dDevice;
|
||||||
|
ID3D12RootSignature* pRootSignature;
|
||||||
|
ID3D12PipelineState* pPipelineState;
|
||||||
|
DXGI_FORMAT RTVFormat;
|
||||||
|
ID3D12Resource* pFontTextureResource;
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||||
|
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||||
|
UINT numFramesInFlight;
|
||||||
|
|
||||||
|
ImGui_ImplDX12_RenderBuffers* pFrameResources;
|
||||||
|
UINT frameIndex;
|
||||||
|
|
||||||
|
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); frameIndex = UINT_MAX; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||||
|
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||||
|
static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffers used during the rendering of a frame
|
||||||
|
struct ImGui_ImplDX12_RenderBuffers
|
||||||
|
{
|
||||||
|
ID3D12Resource* IndexBuffer;
|
||||||
|
ID3D12Resource* VertexBuffer;
|
||||||
|
int IndexBufferSize;
|
||||||
|
int VertexBufferSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VERTEX_CONSTANT_BUFFER_DX12
|
||||||
|
{
|
||||||
|
float mvp[4][4];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
|
||||||
|
// Setup orthographic projection matrix into our constant buffer
|
||||||
|
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
|
||||||
|
VERTEX_CONSTANT_BUFFER_DX12 vertex_constant_buffer;
|
||||||
|
{
|
||||||
|
float L = draw_data->DisplayPos.x;
|
||||||
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
|
float T = draw_data->DisplayPos.y;
|
||||||
|
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||||
|
float mvp[4][4] =
|
||||||
|
{
|
||||||
|
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||||
|
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||||
|
};
|
||||||
|
memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup viewport
|
||||||
|
D3D12_VIEWPORT vp;
|
||||||
|
memset(&vp, 0, sizeof(D3D12_VIEWPORT));
|
||||||
|
vp.Width = draw_data->DisplaySize.x;
|
||||||
|
vp.Height = draw_data->DisplaySize.y;
|
||||||
|
vp.MinDepth = 0.0f;
|
||||||
|
vp.MaxDepth = 1.0f;
|
||||||
|
vp.TopLeftX = vp.TopLeftY = 0.0f;
|
||||||
|
ctx->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
|
// Bind shader and vertex buffers
|
||||||
|
unsigned int stride = sizeof(ImDrawVert);
|
||||||
|
unsigned int offset = 0;
|
||||||
|
D3D12_VERTEX_BUFFER_VIEW vbv;
|
||||||
|
memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW));
|
||||||
|
vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
|
||||||
|
vbv.SizeInBytes = fr->VertexBufferSize * stride;
|
||||||
|
vbv.StrideInBytes = stride;
|
||||||
|
ctx->IASetVertexBuffers(0, 1, &vbv);
|
||||||
|
D3D12_INDEX_BUFFER_VIEW ibv;
|
||||||
|
memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW));
|
||||||
|
ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
|
||||||
|
ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
|
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
|
||||||
|
ctx->IASetIndexBuffer(&ibv);
|
||||||
|
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
ctx->SetPipelineState(bd->pPipelineState);
|
||||||
|
ctx->SetGraphicsRootSignature(bd->pRootSignature);
|
||||||
|
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
|
||||||
|
|
||||||
|
// Setup blend factor
|
||||||
|
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
|
ctx->OMSetBlendFactor(blend_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline void SafeRelease(T*& res)
|
||||||
|
{
|
||||||
|
if (res)
|
||||||
|
res->Release();
|
||||||
|
res = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render function
|
||||||
|
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized
|
||||||
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// FIXME: I'm assuming that this only gets called once per frame!
|
||||||
|
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
bd->frameIndex = bd->frameIndex + 1;
|
||||||
|
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
|
||||||
|
|
||||||
|
// Create and grow vertex/index buffers if needed
|
||||||
|
if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
|
{
|
||||||
|
SafeRelease(fr->VertexBuffer);
|
||||||
|
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
|
D3D12_HEAP_PROPERTIES props;
|
||||||
|
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||||
|
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||||
|
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
|
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
|
D3D12_RESOURCE_DESC desc;
|
||||||
|
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
|
||||||
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
|
desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert);
|
||||||
|
desc.Height = 1;
|
||||||
|
desc.DepthOrArraySize = 1;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||||
|
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&fr->VertexBuffer)) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fr->IndexBuffer == nullptr || fr->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
|
{
|
||||||
|
SafeRelease(fr->IndexBuffer);
|
||||||
|
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
|
D3D12_HEAP_PROPERTIES props;
|
||||||
|
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||||
|
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||||
|
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
|
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
|
D3D12_RESOURCE_DESC desc;
|
||||||
|
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
|
||||||
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
|
desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
|
desc.Height = 1;
|
||||||
|
desc.DepthOrArraySize = 1;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||||
|
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&fr->IndexBuffer)) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload vertex/index data into a single contiguous GPU buffer
|
||||||
|
void* vtx_resource, *idx_resource;
|
||||||
|
D3D12_RANGE range;
|
||||||
|
memset(&range, 0, sizeof(D3D12_RANGE));
|
||||||
|
if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
|
||||||
|
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||||
|
idx_dst += cmd_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
fr->VertexBuffer->Unmap(0, &range);
|
||||||
|
fr->IndexBuffer->Unmap(0, &range);
|
||||||
|
|
||||||
|
// Setup desired DX state
|
||||||
|
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
|
||||||
|
|
||||||
|
// Render command lists
|
||||||
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
|
int global_vtx_offset = 0;
|
||||||
|
int global_idx_offset = 0;
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||||
|
if (pcmd->UserCallback != nullptr)
|
||||||
|
{
|
||||||
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
|
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
|
||||||
|
else
|
||||||
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||||
|
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
||||||
|
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
||||||
|
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||||
|
ctx->RSSetScissorRects(1, &r);
|
||||||
|
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||||
|
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX12_CreateFontsTexture()
|
||||||
|
{
|
||||||
|
// Build texture atlas
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
unsigned char* pixels;
|
||||||
|
int width, height;
|
||||||
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||||
|
|
||||||
|
// Upload texture to graphics system
|
||||||
|
{
|
||||||
|
D3D12_HEAP_PROPERTIES props;
|
||||||
|
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||||
|
props.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||||
|
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
|
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
|
|
||||||
|
D3D12_RESOURCE_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||||
|
desc.Alignment = 0;
|
||||||
|
desc.Width = width;
|
||||||
|
desc.Height = height;
|
||||||
|
desc.DepthOrArraySize = 1;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.SampleDesc.Quality = 0;
|
||||||
|
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||||
|
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
|
||||||
|
ID3D12Resource* pTexture = nullptr;
|
||||||
|
bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||||
|
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&pTexture));
|
||||||
|
|
||||||
|
UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||||
|
UINT uploadSize = height * uploadPitch;
|
||||||
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
|
desc.Alignment = 0;
|
||||||
|
desc.Width = uploadSize;
|
||||||
|
desc.Height = 1;
|
||||||
|
desc.DepthOrArraySize = 1;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.SampleDesc.Quality = 0;
|
||||||
|
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||||
|
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
|
||||||
|
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||||
|
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
|
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
|
|
||||||
|
ID3D12Resource* uploadBuffer = nullptr;
|
||||||
|
HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||||
|
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uploadBuffer));
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
void* mapped = nullptr;
|
||||||
|
D3D12_RANGE range = { 0, uploadSize };
|
||||||
|
hr = uploadBuffer->Map(0, &range, &mapped);
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
memcpy((void*) ((uintptr_t) mapped + y * uploadPitch), pixels + y * width * 4, width * 4);
|
||||||
|
uploadBuffer->Unmap(0, &range);
|
||||||
|
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
|
||||||
|
srcLocation.pResource = uploadBuffer;
|
||||||
|
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.Width = width;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.Height = height;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.Depth = 1;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch;
|
||||||
|
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
|
||||||
|
dstLocation.pResource = pTexture;
|
||||||
|
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
|
dstLocation.SubresourceIndex = 0;
|
||||||
|
|
||||||
|
D3D12_RESOURCE_BARRIER barrier = {};
|
||||||
|
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||||
|
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||||
|
barrier.Transition.pResource = pTexture;
|
||||||
|
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
|
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||||
|
|
||||||
|
ID3D12Fence* fence = nullptr;
|
||||||
|
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
HANDLE event = CreateEvent(0, 0, 0, 0);
|
||||||
|
IM_ASSERT(event != nullptr);
|
||||||
|
|
||||||
|
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||||
|
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||||
|
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||||
|
queueDesc.NodeMask = 1;
|
||||||
|
|
||||||
|
ID3D12CommandQueue* cmdQueue = nullptr;
|
||||||
|
hr = bd->pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
ID3D12CommandAllocator* cmdAlloc = nullptr;
|
||||||
|
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
ID3D12GraphicsCommandList* cmdList = nullptr;
|
||||||
|
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdList));
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, nullptr);
|
||||||
|
cmdList->ResourceBarrier(1, &barrier);
|
||||||
|
|
||||||
|
hr = cmdList->Close();
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList);
|
||||||
|
hr = cmdQueue->Signal(fence, 1);
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
fence->SetEventOnCompletion(1, event);
|
||||||
|
WaitForSingleObject(event, INFINITE);
|
||||||
|
|
||||||
|
cmdList->Release();
|
||||||
|
cmdAlloc->Release();
|
||||||
|
cmdQueue->Release();
|
||||||
|
CloseHandle(event);
|
||||||
|
fence->Release();
|
||||||
|
uploadBuffer->Release();
|
||||||
|
|
||||||
|
// Create texture view
|
||||||
|
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||||
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||||
|
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||||
|
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, bd->hFontSrvCpuDescHandle);
|
||||||
|
SafeRelease(bd->pFontTextureResource);
|
||||||
|
bd->pFontTextureResource = pTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store our identifier
|
||||||
|
// READ THIS IF THE STATIC_ASSERT() TRIGGERS:
|
||||||
|
// - Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||||
|
// - This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||||
|
// [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
|
||||||
|
// [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
||||||
|
// [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
||||||
|
// [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
||||||
|
static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
|
||||||
|
io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
if (!bd || !bd->pd3dDevice)
|
||||||
|
return false;
|
||||||
|
if (bd->pPipelineState)
|
||||||
|
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// Create the root signature
|
||||||
|
{
|
||||||
|
D3D12_DESCRIPTOR_RANGE descRange = {};
|
||||||
|
descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
||||||
|
descRange.NumDescriptors = 1;
|
||||||
|
descRange.BaseShaderRegister = 0;
|
||||||
|
descRange.RegisterSpace = 0;
|
||||||
|
descRange.OffsetInDescriptorsFromTableStart = 0;
|
||||||
|
|
||||||
|
D3D12_ROOT_PARAMETER param[2] = {};
|
||||||
|
|
||||||
|
param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
|
||||||
|
param[0].Constants.ShaderRegister = 0;
|
||||||
|
param[0].Constants.RegisterSpace = 0;
|
||||||
|
param[0].Constants.Num32BitValues = 16;
|
||||||
|
param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
|
||||||
|
|
||||||
|
param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||||
|
param[1].DescriptorTable.NumDescriptorRanges = 1;
|
||||||
|
param[1].DescriptorTable.pDescriptorRanges = &descRange;
|
||||||
|
param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||||
|
|
||||||
|
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||||
|
D3D12_STATIC_SAMPLER_DESC staticSampler = {};
|
||||||
|
staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
staticSampler.MipLODBias = 0.f;
|
||||||
|
staticSampler.MaxAnisotropy = 0;
|
||||||
|
staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||||
|
staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
|
||||||
|
staticSampler.MinLOD = 0.f;
|
||||||
|
staticSampler.MaxLOD = 0.f;
|
||||||
|
staticSampler.ShaderRegister = 0;
|
||||||
|
staticSampler.RegisterSpace = 0;
|
||||||
|
staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||||
|
|
||||||
|
D3D12_ROOT_SIGNATURE_DESC desc = {};
|
||||||
|
desc.NumParameters = _countof(param);
|
||||||
|
desc.pParameters = param;
|
||||||
|
desc.NumStaticSamplers = 1;
|
||||||
|
desc.pStaticSamplers = &staticSampler;
|
||||||
|
desc.Flags =
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
|
||||||
|
|
||||||
|
// Load d3d12.dll and D3D12SerializeRootSignature() function address dynamically to facilitate using with D3D12On7.
|
||||||
|
// See if any version of d3d12.dll is already loaded in the process. If so, give preference to that.
|
||||||
|
static HINSTANCE d3d12_dll = ::GetModuleHandleA("d3d12.dll");
|
||||||
|
if (d3d12_dll == nullptr)
|
||||||
|
{
|
||||||
|
// Attempt to load d3d12.dll from local directories. This will only succeed if
|
||||||
|
// (1) the current OS is Windows 7, and
|
||||||
|
// (2) there exists a version of d3d12.dll for Windows 7 (D3D12On7) in one of the following directories.
|
||||||
|
// See https://github.com/ocornut/imgui/pull/3696 for details.
|
||||||
|
const char* localD3d12Paths[] = { ".\\d3d12.dll", ".\\d3d12on7\\d3d12.dll", ".\\12on7\\d3d12.dll" }; // A. current directory, B. used by some games, C. used in Microsoft D3D12On7 sample
|
||||||
|
for (int i = 0; i < IM_ARRAYSIZE(localD3d12Paths); i++)
|
||||||
|
if ((d3d12_dll = ::LoadLibraryA(localD3d12Paths[i])) != nullptr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If failed, we are on Windows >= 10.
|
||||||
|
if (d3d12_dll == nullptr)
|
||||||
|
d3d12_dll = ::LoadLibraryA("d3d12.dll");
|
||||||
|
|
||||||
|
if (d3d12_dll == nullptr)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFn = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)::GetProcAddress(d3d12_dll, "D3D12SerializeRootSignature");
|
||||||
|
if (D3D12SerializeRootSignatureFn == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ID3DBlob* blob = nullptr;
|
||||||
|
if (D3D12SerializeRootSignatureFn(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, nullptr) != S_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bd->pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&bd->pRootSignature));
|
||||||
|
blob->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||||
|
// If you would like to use this DX12 sample code but remove this dependency you can:
|
||||||
|
// 1) compile once, save the compiled shader blobs into a file or source code and assign them to psoDesc.VS/PS [preferred solution]
|
||||||
|
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||||
|
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||||
|
|
||||||
|
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
|
||||||
|
memset(&psoDesc, 0, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
|
||||||
|
psoDesc.NodeMask = 1;
|
||||||
|
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||||
|
psoDesc.pRootSignature = bd->pRootSignature;
|
||||||
|
psoDesc.SampleMask = UINT_MAX;
|
||||||
|
psoDesc.NumRenderTargets = 1;
|
||||||
|
psoDesc.RTVFormats[0] = bd->RTVFormat;
|
||||||
|
psoDesc.SampleDesc.Count = 1;
|
||||||
|
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
|
||||||
|
|
||||||
|
ID3DBlob* vertexShaderBlob;
|
||||||
|
ID3DBlob* pixelShaderBlob;
|
||||||
|
|
||||||
|
// Create the vertex shader
|
||||||
|
{
|
||||||
|
static const char* vertexShader =
|
||||||
|
"cbuffer vertexBuffer : register(b0) \
|
||||||
|
{\
|
||||||
|
float4x4 ProjectionMatrix; \
|
||||||
|
};\
|
||||||
|
struct VS_INPUT\
|
||||||
|
{\
|
||||||
|
float2 pos : POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
\
|
||||||
|
struct PS_INPUT\
|
||||||
|
{\
|
||||||
|
float4 pos : SV_POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
\
|
||||||
|
PS_INPUT main(VS_INPUT input)\
|
||||||
|
{\
|
||||||
|
PS_INPUT output;\
|
||||||
|
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
|
||||||
|
output.col = input.col;\
|
||||||
|
output.uv = input.uv;\
|
||||||
|
return output;\
|
||||||
|
}";
|
||||||
|
|
||||||
|
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_5_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||||
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
|
psoDesc.VS = { vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize() };
|
||||||
|
|
||||||
|
// Create the input layout
|
||||||
|
static D3D12_INPUT_ELEMENT_DESC local_layout[] =
|
||||||
|
{
|
||||||
|
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||||
|
};
|
||||||
|
psoDesc.InputLayout = { local_layout, 3 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the pixel shader
|
||||||
|
{
|
||||||
|
static const char* pixelShader =
|
||||||
|
"struct PS_INPUT\
|
||||||
|
{\
|
||||||
|
float4 pos : SV_POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
SamplerState sampler0 : register(s0);\
|
||||||
|
Texture2D texture0 : register(t0);\
|
||||||
|
\
|
||||||
|
float4 main(PS_INPUT input) : SV_Target\
|
||||||
|
{\
|
||||||
|
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||||
|
return out_col; \
|
||||||
|
}";
|
||||||
|
|
||||||
|
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_5_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||||
|
{
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
|
}
|
||||||
|
psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the blending setup
|
||||||
|
{
|
||||||
|
D3D12_BLEND_DESC& desc = psoDesc.BlendState;
|
||||||
|
desc.AlphaToCoverageEnable = false;
|
||||||
|
desc.RenderTarget[0].BlendEnable = true;
|
||||||
|
desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
|
||||||
|
desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
|
||||||
|
desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||||
|
desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the rasterizer state
|
||||||
|
{
|
||||||
|
D3D12_RASTERIZER_DESC& desc = psoDesc.RasterizerState;
|
||||||
|
desc.FillMode = D3D12_FILL_MODE_SOLID;
|
||||||
|
desc.CullMode = D3D12_CULL_MODE_NONE;
|
||||||
|
desc.FrontCounterClockwise = FALSE;
|
||||||
|
desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
|
||||||
|
desc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
|
||||||
|
desc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||||
|
desc.DepthClipEnable = true;
|
||||||
|
desc.MultisampleEnable = FALSE;
|
||||||
|
desc.AntialiasedLineEnable = FALSE;
|
||||||
|
desc.ForcedSampleCount = 0;
|
||||||
|
desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create depth-stencil State
|
||||||
|
{
|
||||||
|
D3D12_DEPTH_STENCIL_DESC& desc = psoDesc.DepthStencilState;
|
||||||
|
desc.DepthEnable = false;
|
||||||
|
desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
|
||||||
|
desc.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||||
|
desc.StencilEnable = false;
|
||||||
|
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
|
||||||
|
desc.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||||
|
desc.BackFace = desc.FrontFace;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT result_pipeline_state = bd->pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&bd->pPipelineState));
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
pixelShaderBlob->Release();
|
||||||
|
if (result_pipeline_state != S_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ImGui_ImplDX12_CreateFontsTexture();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
if (!bd || !bd->pd3dDevice)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
SafeRelease(bd->pRootSignature);
|
||||||
|
SafeRelease(bd->pPipelineState);
|
||||||
|
SafeRelease(bd->pFontTextureResource);
|
||||||
|
io.Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||||
|
|
||||||
|
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||||
|
SafeRelease(fr->IndexBuffer);
|
||||||
|
SafeRelease(fr->VertexBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
|
|
||||||
|
// Setup backend capabilities flags
|
||||||
|
ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)();
|
||||||
|
io.BackendRendererUserData = (void*)bd;
|
||||||
|
io.BackendRendererName = "imgui_impl_dx12";
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
|
|
||||||
|
bd->pd3dDevice = device;
|
||||||
|
bd->RTVFormat = rtv_format;
|
||||||
|
bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
|
||||||
|
bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
|
||||||
|
bd->pFrameResources = new ImGui_ImplDX12_RenderBuffers[num_frames_in_flight];
|
||||||
|
bd->numFramesInFlight = num_frames_in_flight;
|
||||||
|
bd->pd3dSrvDescHeap = cbv_srv_heap;
|
||||||
|
bd->frameIndex = UINT_MAX;
|
||||||
|
|
||||||
|
// Create buffers with a default size (they will later be grown as needed)
|
||||||
|
for (int i = 0; i < num_frames_in_flight; i++)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||||
|
fr->IndexBuffer = nullptr;
|
||||||
|
fr->VertexBuffer = nullptr;
|
||||||
|
fr->IndexBufferSize = 10000;
|
||||||
|
fr->VertexBufferSize = 5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX12_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
// Clean up windows and device objects
|
||||||
|
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||||
|
delete[] bd->pFrameResources;
|
||||||
|
io.BackendRendererName = nullptr;
|
||||||
|
io.BackendRendererUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX12_NewFrame()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX12_Init()?");
|
||||||
|
|
||||||
|
if (!bd->pPipelineState)
|
||||||
|
ImGui_ImplDX12_CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
46
ScreenRecoder/ImGui/imgui_impl_dx12.h
Normal file
46
ScreenRecoder/ImGui/imgui_impl_dx12.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX12
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
|
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||||
|
// See imgui_impl_dx12.cpp file for details.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include <dxgiformat.h> // DXGI_FORMAT
|
||||||
|
|
||||||
|
struct ID3D12Device;
|
||||||
|
struct ID3D12DescriptorHeap;
|
||||||
|
struct ID3D12GraphicsCommandList;
|
||||||
|
struct D3D12_CPU_DESCRIPTOR_HANDLE;
|
||||||
|
struct D3D12_GPU_DESCRIPTOR_HANDLE;
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
|
||||||
|
// cmd_list is the command list that the implementation will use to render imgui draw lists.
|
||||||
|
// Before calling the render function, caller must prepare cmd_list by resetting it and setting the appropriate
|
||||||
|
// render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle.
|
||||||
|
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture.
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list);
|
||||||
|
|
||||||
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
411
ScreenRecoder/ImGui/imgui_impl_dx9.cpp
Normal file
411
ScreenRecoder/ImGui/imgui_impl_dx9.cpp
Normal file
@ -0,0 +1,411 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX9
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
// CHANGELOG
|
||||||
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
|
||||||
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
|
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||||
|
// 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1.
|
||||||
|
// 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
|
// 2021-04-23: DirectX9: Explicitly setting up more graphics states to increase compatibility with unusual non-default states.
|
||||||
|
// 2021-03-18: DirectX9: Calling IDirect3DStateBlock9::Capture() after CreateStateBlock() as a workaround for state restoring issues (see #3857).
|
||||||
|
// 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file.
|
||||||
|
// 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer.
|
||||||
|
// 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||||
|
// 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||||
|
// 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects().
|
||||||
|
// 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288.
|
||||||
|
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||||
|
// 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example.
|
||||||
|
// 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||||
|
// 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud.
|
||||||
|
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself.
|
||||||
|
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui_impl_dx9.h"
|
||||||
|
|
||||||
|
// DirectX
|
||||||
|
#include <d3d9.h>
|
||||||
|
|
||||||
|
// DirectX data
|
||||||
|
struct ImGui_ImplDX9_Data
|
||||||
|
{
|
||||||
|
LPDIRECT3DDEVICE9 pd3dDevice;
|
||||||
|
LPDIRECT3DVERTEXBUFFER9 pVB;
|
||||||
|
LPDIRECT3DINDEXBUFFER9 pIB;
|
||||||
|
LPDIRECT3DTEXTURE9 FontTexture;
|
||||||
|
int VertexBufferSize;
|
||||||
|
int IndexBufferSize;
|
||||||
|
|
||||||
|
ImGui_ImplDX9_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CUSTOMVERTEX
|
||||||
|
{
|
||||||
|
float pos[3];
|
||||||
|
D3DCOLOR col;
|
||||||
|
float uv[2];
|
||||||
|
};
|
||||||
|
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||||
|
|
||||||
|
#ifdef IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
#define IMGUI_COL_TO_DX9_ARGB(_COL) (_COL)
|
||||||
|
#else
|
||||||
|
#define IMGUI_COL_TO_DX9_ARGB(_COL) (((_COL) & 0xFF00FF00) | (((_COL) & 0xFF0000) >> 16) | (((_COL) & 0xFF) << 16))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||||
|
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||||
|
static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
|
||||||
|
// Setup viewport
|
||||||
|
D3DVIEWPORT9 vp;
|
||||||
|
vp.X = vp.Y = 0;
|
||||||
|
vp.Width = (DWORD)draw_data->DisplaySize.x;
|
||||||
|
vp.Height = (DWORD)draw_data->DisplaySize.y;
|
||||||
|
vp.MinZ = 0.0f;
|
||||||
|
vp.MaxZ = 1.0f;
|
||||||
|
bd->pd3dDevice->SetViewport(&vp);
|
||||||
|
|
||||||
|
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling.
|
||||||
|
bd->pd3dDevice->SetPixelShader(nullptr);
|
||||||
|
bd->pd3dDevice->SetVertexShader(nullptr);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
|
||||||
|
bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||||
|
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||||
|
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||||
|
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||||
|
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||||
|
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||||
|
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||||
|
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||||
|
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||||
|
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||||
|
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||||
|
|
||||||
|
// Setup orthographic projection matrix
|
||||||
|
// 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.
|
||||||
|
// Being agnostic of whether <d3dx9.h> or <DirectXMath.h> can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
|
||||||
|
{
|
||||||
|
float L = draw_data->DisplayPos.x + 0.5f;
|
||||||
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f;
|
||||||
|
float T = draw_data->DisplayPos.y + 0.5f;
|
||||||
|
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f;
|
||||||
|
D3DMATRIX mat_identity = { { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } } };
|
||||||
|
D3DMATRIX mat_projection =
|
||||||
|
{ { {
|
||||||
|
2.0f/(R-L), 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 2.0f/(T-B), 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.5f, 0.0f,
|
||||||
|
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
|
||||||
|
} } };
|
||||||
|
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
|
||||||
|
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
|
||||||
|
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render function.
|
||||||
|
void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized
|
||||||
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Create and grow buffers if needed
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
|
{
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
|
if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
|
{
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
|
if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backup the DX9 state
|
||||||
|
IDirect3DStateBlock9* d3d9_state_block = nullptr;
|
||||||
|
if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
|
||||||
|
return;
|
||||||
|
if (d3d9_state_block->Capture() < 0)
|
||||||
|
{
|
||||||
|
d3d9_state_block->Release();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
|
||||||
|
D3DMATRIX last_world, last_view, last_projection;
|
||||||
|
bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world);
|
||||||
|
bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view);
|
||||||
|
bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection);
|
||||||
|
|
||||||
|
// Allocate buffers
|
||||||
|
CUSTOMVERTEX* vtx_dst;
|
||||||
|
ImDrawIdx* idx_dst;
|
||||||
|
if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
|
||||||
|
{
|
||||||
|
d3d9_state_block->Release();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
|
||||||
|
{
|
||||||
|
bd->pVB->Unlock();
|
||||||
|
d3d9_state_block->Release();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format.
|
||||||
|
// FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and
|
||||||
|
// 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data;
|
||||||
|
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
||||||
|
{
|
||||||
|
vtx_dst->pos[0] = vtx_src->pos.x;
|
||||||
|
vtx_dst->pos[1] = vtx_src->pos.y;
|
||||||
|
vtx_dst->pos[2] = 0.0f;
|
||||||
|
vtx_dst->col = IMGUI_COL_TO_DX9_ARGB(vtx_src->col);
|
||||||
|
vtx_dst->uv[0] = vtx_src->uv.x;
|
||||||
|
vtx_dst->uv[1] = vtx_src->uv.y;
|
||||||
|
vtx_dst++;
|
||||||
|
vtx_src++;
|
||||||
|
}
|
||||||
|
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
idx_dst += cmd_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
bd->pVB->Unlock();
|
||||||
|
bd->pIB->Unlock();
|
||||||
|
bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
|
||||||
|
bd->pd3dDevice->SetIndices(bd->pIB);
|
||||||
|
bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
|
||||||
|
|
||||||
|
// Setup desired DX state
|
||||||
|
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||||
|
|
||||||
|
// Render command lists
|
||||||
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
|
int global_vtx_offset = 0;
|
||||||
|
int global_idx_offset = 0;
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||||
|
if (pcmd->UserCallback != nullptr)
|
||||||
|
{
|
||||||
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
|
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||||
|
else
|
||||||
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||||
|
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
|
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
||||||
|
bd->pd3dDevice->SetTexture(0, texture);
|
||||||
|
bd->pd3dDevice->SetScissorRect(&r);
|
||||||
|
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||||
|
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the DX9 transform
|
||||||
|
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
|
||||||
|
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
|
||||||
|
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection);
|
||||||
|
|
||||||
|
// Restore the DX9 state
|
||||||
|
d3d9_state_block->Apply();
|
||||||
|
d3d9_state_block->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
|
|
||||||
|
// Setup backend capabilities flags
|
||||||
|
ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)();
|
||||||
|
io.BackendRendererUserData = (void*)bd;
|
||||||
|
io.BackendRendererName = "imgui_impl_dx9";
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
|
|
||||||
|
bd->pd3dDevice = device;
|
||||||
|
bd->pd3dDevice->AddRef();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX9_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||||
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
|
io.BackendRendererName = nullptr;
|
||||||
|
io.BackendRendererUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplDX9_CheckFormatSupport(IDirect3DDevice9* pDevice, D3DFORMAT format)
|
||||||
|
{
|
||||||
|
IDirect3D9* pd3d = nullptr;
|
||||||
|
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
|
||||||
|
return false;
|
||||||
|
D3DDEVICE_CREATION_PARAMETERS param = {};
|
||||||
|
D3DDISPLAYMODE mode = {};
|
||||||
|
if (pDevice->GetCreationParameters(¶m) != D3D_OK || pDevice->GetDisplayMode(0, &mode) != D3D_OK)
|
||||||
|
{
|
||||||
|
pd3d->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Font texture should support linear filter, color blend and write to render-target
|
||||||
|
bool support = (pd3d->CheckDeviceFormat(param.AdapterOrdinal, param.DeviceType, mode.Format, D3DUSAGE_DYNAMIC | D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, format)) == D3D_OK;
|
||||||
|
pd3d->Release();
|
||||||
|
return support;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||||
|
{
|
||||||
|
// Build texture atlas
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
unsigned char* pixels;
|
||||||
|
int width, height, bytes_per_pixel;
|
||||||
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel);
|
||||||
|
|
||||||
|
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
||||||
|
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
const bool rgba_support = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
||||||
|
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
||||||
|
{
|
||||||
|
ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel);
|
||||||
|
for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++)
|
||||||
|
*dst = IMGUI_COL_TO_DX9_ARGB(*src);
|
||||||
|
pixels = (unsigned char*)dst_start;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const bool rgba_support = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Upload texture to graphics system
|
||||||
|
bd->FontTexture = nullptr;
|
||||||
|
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, rgba_support ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
||||||
|
return false;
|
||||||
|
D3DLOCKED_RECT tex_locked_rect;
|
||||||
|
if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK)
|
||||||
|
return false;
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel);
|
||||||
|
bd->FontTexture->UnlockRect(0);
|
||||||
|
|
||||||
|
// Store our identifier
|
||||||
|
io.Fonts->SetTexID((ImTextureID)bd->FontTexture);
|
||||||
|
|
||||||
|
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
||||||
|
ImGui::MemFree(pixels);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX9_CreateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
if (!bd || !bd->pd3dDevice)
|
||||||
|
return false;
|
||||||
|
if (!ImGui_ImplDX9_CreateFontsTexture())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX9_InvalidateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
if (!bd || !bd->pd3dDevice)
|
||||||
|
return;
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX9_NewFrame()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX9_Init()?");
|
||||||
|
|
||||||
|
if (!bd->FontTexture)
|
||||||
|
ImGui_ImplDX9_CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
32
ScreenRecoder/ImGui/imgui_impl_dx9.h
Normal file
32
ScreenRecoder/ImGui/imgui_impl_dx9.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX9
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
struct IDirect3DDevice9;
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
925
ScreenRecoder/ImGui/imgui_impl_win32.cpp
Normal file
925
ScreenRecoder/ImGui/imgui_impl_win32.cpp
Normal file
@ -0,0 +1,925 @@
|
|||||||
|
// dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
|
||||||
|
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||||
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||||
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||||
|
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||||
|
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
// Configuration flags to add in your imconfig file:
|
||||||
|
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.
|
||||||
|
|
||||||
|
// CHANGELOG
|
||||||
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768)
|
||||||
|
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||||
|
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
|
||||||
|
// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
|
||||||
|
// 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218)
|
||||||
|
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702)
|
||||||
|
// 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162)
|
||||||
|
// 2023-02-02: Inputs: Flipping WM_MOUSEHWHEEL (horizontal mouse-wheel) value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463)
|
||||||
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
|
// 2022-09-28: Inputs: Convert WM_CHAR values with MultiByteToWideChar() when window class was registered as MBCS (not Unicode).
|
||||||
|
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||||
|
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||||
|
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
|
||||||
|
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||||
|
// 2022-01-17: Inputs: always update key mods next and before a key event (not in NewFrame) to fix input queue with very low framerates.
|
||||||
|
// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
|
||||||
|
// 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
|
||||||
|
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||||
|
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
|
||||||
|
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
|
||||||
|
// 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host window doesn't have focus.
|
||||||
|
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using TrackMouseEvent() to receive WM_MOUSELEAVE events).
|
||||||
|
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||||
|
// 2021-06-08: Fixed ImGui_ImplWin32_EnableDpiAwareness() and ImGui_ImplWin32_GetDpiScaleForMonitor() to handle Windows 8.1/10 features without a manifest (per-monitor DPI, and properly calls SetProcessDpiAwareness() on 8.1).
|
||||||
|
// 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS).
|
||||||
|
// 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
|
||||||
|
// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1.
|
||||||
|
// 2021-01-25: Inputs: Dynamically loading XInput DLL.
|
||||||
|
// 2020-12-04: Misc: Fixed setting of io.DisplaySize to invalid/uninitialized data when after hwnd has been closed.
|
||||||
|
// 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs)
|
||||||
|
// 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions.
|
||||||
|
// 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT.
|
||||||
|
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
|
||||||
|
// 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter().
|
||||||
|
// 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent.
|
||||||
|
// 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages.
|
||||||
|
// 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
|
||||||
|
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
|
||||||
|
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
|
||||||
|
// 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads).
|
||||||
|
// 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples.
|
||||||
|
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag.
|
||||||
|
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
|
||||||
|
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
|
||||||
|
// 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
|
||||||
|
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||||
|
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
|
||||||
|
// 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert.
|
||||||
|
// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
|
||||||
|
// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read.
|
||||||
|
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
|
||||||
|
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set.
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui_impl_win32.h"
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <dwmapi.h>
|
||||||
|
|
||||||
|
// Using XInput for gamepad (will load DLL dynamically)
|
||||||
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
#include <xinput.h>
|
||||||
|
typedef DWORD(WINAPI* PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||||
|
typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Clang/GCC warnings with -Weverything
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
||||||
|
#endif
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ImGui_ImplWin32_Data
|
||||||
|
{
|
||||||
|
HWND hWnd;
|
||||||
|
HWND MouseHwnd;
|
||||||
|
int MouseTrackedArea; // 0: not tracked, 1: client are, 2: non-client area
|
||||||
|
int MouseButtonsDown;
|
||||||
|
INT64 Time;
|
||||||
|
INT64 TicksPerSecond;
|
||||||
|
ImGuiMouseCursor LastMouseCursor;
|
||||||
|
UINT32 KeyboardCodePage;
|
||||||
|
|
||||||
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
bool HasGamepad;
|
||||||
|
bool WantUpdateHasGamepad;
|
||||||
|
HMODULE XInputDLL;
|
||||||
|
PFN_XInputGetCapabilities XInputGetCapabilities;
|
||||||
|
PFN_XInputGetState XInputGetState;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ImGui_ImplWin32_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
||||||
|
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||||
|
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
|
||||||
|
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
||||||
|
static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
static void ImGui_ImplWin32_UpdateKeyboardCodePage()
|
||||||
|
{
|
||||||
|
// Retrieve keyboard code page, required for handling of non-Unicode Windows.
|
||||||
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
|
HKL keyboard_layout = ::GetKeyboardLayout(0);
|
||||||
|
LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT);
|
||||||
|
if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0)
|
||||||
|
bd->KeyboardCodePage = CP_ACP; // Fallback to default ANSI code page when fails.
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||||
|
|
||||||
|
INT64 perf_frequency, perf_counter;
|
||||||
|
if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&perf_frequency))
|
||||||
|
return false;
|
||||||
|
if (!::QueryPerformanceCounter((LARGE_INTEGER*)&perf_counter))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Setup backend capabilities flags
|
||||||
|
ImGui_ImplWin32_Data* bd = IM_NEW(ImGui_ImplWin32_Data)();
|
||||||
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
|
io.BackendPlatformName = "imgui_impl_win32";
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||||
|
|
||||||
|
bd->hWnd = (HWND)hwnd;
|
||||||
|
bd->TicksPerSecond = perf_frequency;
|
||||||
|
bd->Time = perf_counter;
|
||||||
|
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||||
|
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
||||||
|
|
||||||
|
// Set platform dependent data in viewport
|
||||||
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
|
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
|
||||||
|
IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch
|
||||||
|
|
||||||
|
// Dynamically load XInput library
|
||||||
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
bd->WantUpdateHasGamepad = true;
|
||||||
|
const char* xinput_dll_names[] =
|
||||||
|
{
|
||||||
|
"xinput1_4.dll", // Windows 8+
|
||||||
|
"xinput1_3.dll", // DirectX SDK
|
||||||
|
"xinput9_1_0.dll", // Windows Vista, Windows 7
|
||||||
|
"xinput1_2.dll", // DirectX SDK
|
||||||
|
"xinput1_1.dll" // DirectX SDK
|
||||||
|
};
|
||||||
|
for (int n = 0; n < IM_ARRAYSIZE(xinput_dll_names); n++)
|
||||||
|
if (HMODULE dll = ::LoadLibraryA(xinput_dll_names[n]))
|
||||||
|
{
|
||||||
|
bd->XInputDLL = dll;
|
||||||
|
bd->XInputGetCapabilities = (PFN_XInputGetCapabilities)::GetProcAddress(dll, "XInputGetCapabilities");
|
||||||
|
bd->XInputGetState = (PFN_XInputGetState)::GetProcAddress(dll, "XInputGetState");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd)
|
||||||
|
{
|
||||||
|
return ImGui_ImplWin32_InitEx(hwnd, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd)
|
||||||
|
{
|
||||||
|
// OpenGL needs CS_OWNDC
|
||||||
|
return ImGui_ImplWin32_InitEx(hwnd, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplWin32_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
// Unload XInput library
|
||||||
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
if (bd->XInputDLL)
|
||||||
|
::FreeLibrary(bd->XInputDLL);
|
||||||
|
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
|
||||||
|
io.BackendPlatformName = nullptr;
|
||||||
|
io.BackendPlatformUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||||
|
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||||
|
{
|
||||||
|
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||||
|
::SetCursor(nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Show OS mouse cursor
|
||||||
|
LPTSTR win32_cursor = IDC_ARROW;
|
||||||
|
switch (imgui_cursor)
|
||||||
|
{
|
||||||
|
case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break;
|
||||||
|
case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break;
|
||||||
|
case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break;
|
||||||
|
case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break;
|
||||||
|
case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break;
|
||||||
|
case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
|
||||||
|
case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
|
||||||
|
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
|
||||||
|
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
|
||||||
|
}
|
||||||
|
::SetCursor(::LoadCursor(nullptr, win32_cursor));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsVkDown(int vk)
|
||||||
|
{
|
||||||
|
return (::GetKeyState(vk) & 0x8000) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.AddKeyEvent(key, down);
|
||||||
|
io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code)
|
||||||
|
IM_UNUSED(native_scancode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
||||||
|
{
|
||||||
|
// Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one.
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT))
|
||||||
|
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT);
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
|
||||||
|
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, false, VK_RSHIFT);
|
||||||
|
|
||||||
|
// Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW).
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
|
||||||
|
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN);
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
|
||||||
|
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplWin32_UpdateKeyModifiers()
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL));
|
||||||
|
io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT));
|
||||||
|
io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU));
|
||||||
|
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplWin32_UpdateMouseData()
|
||||||
|
{
|
||||||
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IM_ASSERT(bd->hWnd != 0);
|
||||||
|
|
||||||
|
HWND focused_window = ::GetForegroundWindow();
|
||||||
|
const bool is_app_focused = (focused_window == bd->hWnd);
|
||||||
|
if (is_app_focused)
|
||||||
|
{
|
||||||
|
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||||
|
if (io.WantSetMousePos)
|
||||||
|
{
|
||||||
|
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
||||||
|
if (::ClientToScreen(bd->hWnd, &pos))
|
||||||
|
::SetCursorPos(pos.x, pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
||||||
|
// This also fills a short gap when clicking non-client area: WM_NCMOUSELEAVE -> modal OS move -> gap -> WM_NCMOUSEMOVE
|
||||||
|
if (!io.WantSetMousePos && bd->MouseTrackedArea == 0)
|
||||||
|
{
|
||||||
|
POINT pos;
|
||||||
|
if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
|
||||||
|
io.AddMousePosEvent((float)pos.x, (float)pos.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gamepad navigation mapping
|
||||||
|
static void ImGui_ImplWin32_UpdateGamepads()
|
||||||
|
{
|
||||||
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
|
//if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
|
||||||
|
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
|
||||||
|
if (bd->WantUpdateHasGamepad)
|
||||||
|
{
|
||||||
|
XINPUT_CAPABILITIES caps = {};
|
||||||
|
bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
|
||||||
|
bd->WantUpdateHasGamepad = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||||
|
XINPUT_STATE xinput_state;
|
||||||
|
XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
|
||||||
|
if (!bd->HasGamepad || bd->XInputGetState == nullptr || bd->XInputGetState(0, &xinput_state) != ERROR_SUCCESS)
|
||||||
|
return;
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||||
|
|
||||||
|
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||||
|
#define MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepad.wButtons & BUTTON_ENUM) != 0); }
|
||||||
|
#define MAP_ANALOG(KEY_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); io.AddKeyAnalogEvent(KEY_NO, vn > 0.10f, IM_SATURATE(vn)); }
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadStart, XINPUT_GAMEPAD_START);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadBack, XINPUT_GAMEPAD_BACK);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, XINPUT_GAMEPAD_X);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadFaceRight, XINPUT_GAMEPAD_B);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadFaceUp, XINPUT_GAMEPAD_Y);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadFaceDown, XINPUT_GAMEPAD_A);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, XINPUT_GAMEPAD_DPAD_LEFT);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadDpadRight, XINPUT_GAMEPAD_DPAD_RIGHT);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadDpadUp, XINPUT_GAMEPAD_DPAD_UP);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadDpadDown, XINPUT_GAMEPAD_DPAD_DOWN);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadL1, XINPUT_GAMEPAD_LEFT_SHOULDER);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadR1, XINPUT_GAMEPAD_RIGHT_SHOULDER);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadL2, gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadR2, gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadL3, XINPUT_GAMEPAD_LEFT_THUMB);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadR3, XINPUT_GAMEPAD_RIGHT_THUMB);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadLStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadLStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadLStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadRStickLeft, gamepad.sThumbRX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadRStickRight, gamepad.sThumbRX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadRStickUp, gamepad.sThumbRY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
|
#undef MAP_BUTTON
|
||||||
|
#undef MAP_ANALOG
|
||||||
|
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplWin32_NewFrame()
|
||||||
|
{
|
||||||
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized? Did you call ImGui_ImplWin32_Init()?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
// Setup display size (every frame to accommodate for window resizing)
|
||||||
|
RECT rect = { 0, 0, 0, 0 };
|
||||||
|
::GetClientRect(bd->hWnd, &rect);
|
||||||
|
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
|
||||||
|
|
||||||
|
// Setup time step
|
||||||
|
INT64 current_time = 0;
|
||||||
|
::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time);
|
||||||
|
io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
|
||||||
|
bd->Time = current_time;
|
||||||
|
|
||||||
|
// Update OS mouse position
|
||||||
|
ImGui_ImplWin32_UpdateMouseData();
|
||||||
|
|
||||||
|
// Process workarounds for known Windows key handling issues
|
||||||
|
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
|
||||||
|
|
||||||
|
// Update OS mouse cursor with the cursor requested by imgui
|
||||||
|
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
||||||
|
if (bd->LastMouseCursor != mouse_cursor)
|
||||||
|
{
|
||||||
|
bd->LastMouseCursor = mouse_cursor;
|
||||||
|
ImGui_ImplWin32_UpdateMouseCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update game controllers (if enabled and available)
|
||||||
|
ImGui_ImplWin32_UpdateGamepads();
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED, we assign it an arbitrary value to make code more readable (VK_ codes go up to 255)
|
||||||
|
#define IM_VK_KEYPAD_ENTER (VK_RETURN + 256)
|
||||||
|
|
||||||
|
// Map VK_xxx to ImGuiKey_xxx.
|
||||||
|
static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
||||||
|
{
|
||||||
|
switch (wParam)
|
||||||
|
{
|
||||||
|
case VK_TAB: return ImGuiKey_Tab;
|
||||||
|
case VK_LEFT: return ImGuiKey_LeftArrow;
|
||||||
|
case VK_RIGHT: return ImGuiKey_RightArrow;
|
||||||
|
case VK_UP: return ImGuiKey_UpArrow;
|
||||||
|
case VK_DOWN: return ImGuiKey_DownArrow;
|
||||||
|
case VK_PRIOR: return ImGuiKey_PageUp;
|
||||||
|
case VK_NEXT: return ImGuiKey_PageDown;
|
||||||
|
case VK_HOME: return ImGuiKey_Home;
|
||||||
|
case VK_END: return ImGuiKey_End;
|
||||||
|
case VK_INSERT: return ImGuiKey_Insert;
|
||||||
|
case VK_DELETE: return ImGuiKey_Delete;
|
||||||
|
case VK_BACK: return ImGuiKey_Backspace;
|
||||||
|
case VK_SPACE: return ImGuiKey_Space;
|
||||||
|
case VK_RETURN: return ImGuiKey_Enter;
|
||||||
|
case VK_ESCAPE: return ImGuiKey_Escape;
|
||||||
|
case VK_OEM_7: return ImGuiKey_Apostrophe;
|
||||||
|
case VK_OEM_COMMA: return ImGuiKey_Comma;
|
||||||
|
case VK_OEM_MINUS: return ImGuiKey_Minus;
|
||||||
|
case VK_OEM_PERIOD: return ImGuiKey_Period;
|
||||||
|
case VK_OEM_2: return ImGuiKey_Slash;
|
||||||
|
case VK_OEM_1: return ImGuiKey_Semicolon;
|
||||||
|
case VK_OEM_PLUS: return ImGuiKey_Equal;
|
||||||
|
case VK_OEM_4: return ImGuiKey_LeftBracket;
|
||||||
|
case VK_OEM_5: return ImGuiKey_Backslash;
|
||||||
|
case VK_OEM_6: return ImGuiKey_RightBracket;
|
||||||
|
case VK_OEM_3: return ImGuiKey_GraveAccent;
|
||||||
|
case VK_CAPITAL: return ImGuiKey_CapsLock;
|
||||||
|
case VK_SCROLL: return ImGuiKey_ScrollLock;
|
||||||
|
case VK_NUMLOCK: return ImGuiKey_NumLock;
|
||||||
|
case VK_SNAPSHOT: return ImGuiKey_PrintScreen;
|
||||||
|
case VK_PAUSE: return ImGuiKey_Pause;
|
||||||
|
case VK_NUMPAD0: return ImGuiKey_Keypad0;
|
||||||
|
case VK_NUMPAD1: return ImGuiKey_Keypad1;
|
||||||
|
case VK_NUMPAD2: return ImGuiKey_Keypad2;
|
||||||
|
case VK_NUMPAD3: return ImGuiKey_Keypad3;
|
||||||
|
case VK_NUMPAD4: return ImGuiKey_Keypad4;
|
||||||
|
case VK_NUMPAD5: return ImGuiKey_Keypad5;
|
||||||
|
case VK_NUMPAD6: return ImGuiKey_Keypad6;
|
||||||
|
case VK_NUMPAD7: return ImGuiKey_Keypad7;
|
||||||
|
case VK_NUMPAD8: return ImGuiKey_Keypad8;
|
||||||
|
case VK_NUMPAD9: return ImGuiKey_Keypad9;
|
||||||
|
case VK_DECIMAL: return ImGuiKey_KeypadDecimal;
|
||||||
|
case VK_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||||
|
case VK_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||||
|
case VK_SUBTRACT: return ImGuiKey_KeypadSubtract;
|
||||||
|
case VK_ADD: return ImGuiKey_KeypadAdd;
|
||||||
|
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
|
||||||
|
case VK_LSHIFT: return ImGuiKey_LeftShift;
|
||||||
|
case VK_LCONTROL: return ImGuiKey_LeftCtrl;
|
||||||
|
case VK_LMENU: return ImGuiKey_LeftAlt;
|
||||||
|
case VK_LWIN: return ImGuiKey_LeftSuper;
|
||||||
|
case VK_RSHIFT: return ImGuiKey_RightShift;
|
||||||
|
case VK_RCONTROL: return ImGuiKey_RightCtrl;
|
||||||
|
case VK_RMENU: return ImGuiKey_RightAlt;
|
||||||
|
case VK_RWIN: return ImGuiKey_RightSuper;
|
||||||
|
case VK_APPS: return ImGuiKey_Menu;
|
||||||
|
case '0': return ImGuiKey_0;
|
||||||
|
case '1': return ImGuiKey_1;
|
||||||
|
case '2': return ImGuiKey_2;
|
||||||
|
case '3': return ImGuiKey_3;
|
||||||
|
case '4': return ImGuiKey_4;
|
||||||
|
case '5': return ImGuiKey_5;
|
||||||
|
case '6': return ImGuiKey_6;
|
||||||
|
case '7': return ImGuiKey_7;
|
||||||
|
case '8': return ImGuiKey_8;
|
||||||
|
case '9': return ImGuiKey_9;
|
||||||
|
case 'A': return ImGuiKey_A;
|
||||||
|
case 'B': return ImGuiKey_B;
|
||||||
|
case 'C': return ImGuiKey_C;
|
||||||
|
case 'D': return ImGuiKey_D;
|
||||||
|
case 'E': return ImGuiKey_E;
|
||||||
|
case 'F': return ImGuiKey_F;
|
||||||
|
case 'G': return ImGuiKey_G;
|
||||||
|
case 'H': return ImGuiKey_H;
|
||||||
|
case 'I': return ImGuiKey_I;
|
||||||
|
case 'J': return ImGuiKey_J;
|
||||||
|
case 'K': return ImGuiKey_K;
|
||||||
|
case 'L': return ImGuiKey_L;
|
||||||
|
case 'M': return ImGuiKey_M;
|
||||||
|
case 'N': return ImGuiKey_N;
|
||||||
|
case 'O': return ImGuiKey_O;
|
||||||
|
case 'P': return ImGuiKey_P;
|
||||||
|
case 'Q': return ImGuiKey_Q;
|
||||||
|
case 'R': return ImGuiKey_R;
|
||||||
|
case 'S': return ImGuiKey_S;
|
||||||
|
case 'T': return ImGuiKey_T;
|
||||||
|
case 'U': return ImGuiKey_U;
|
||||||
|
case 'V': return ImGuiKey_V;
|
||||||
|
case 'W': return ImGuiKey_W;
|
||||||
|
case 'X': return ImGuiKey_X;
|
||||||
|
case 'Y': return ImGuiKey_Y;
|
||||||
|
case 'Z': return ImGuiKey_Z;
|
||||||
|
case VK_F1: return ImGuiKey_F1;
|
||||||
|
case VK_F2: return ImGuiKey_F2;
|
||||||
|
case VK_F3: return ImGuiKey_F3;
|
||||||
|
case VK_F4: return ImGuiKey_F4;
|
||||||
|
case VK_F5: return ImGuiKey_F5;
|
||||||
|
case VK_F6: return ImGuiKey_F6;
|
||||||
|
case VK_F7: return ImGuiKey_F7;
|
||||||
|
case VK_F8: return ImGuiKey_F8;
|
||||||
|
case VK_F9: return ImGuiKey_F9;
|
||||||
|
case VK_F10: return ImGuiKey_F10;
|
||||||
|
case VK_F11: return ImGuiKey_F11;
|
||||||
|
case VK_F12: return ImGuiKey_F12;
|
||||||
|
case VK_F13: return ImGuiKey_F13;
|
||||||
|
case VK_F14: return ImGuiKey_F14;
|
||||||
|
case VK_F15: return ImGuiKey_F15;
|
||||||
|
case VK_F16: return ImGuiKey_F16;
|
||||||
|
case VK_F17: return ImGuiKey_F17;
|
||||||
|
case VK_F18: return ImGuiKey_F18;
|
||||||
|
case VK_F19: return ImGuiKey_F19;
|
||||||
|
case VK_F20: return ImGuiKey_F20;
|
||||||
|
case VK_F21: return ImGuiKey_F21;
|
||||||
|
case VK_F22: return ImGuiKey_F22;
|
||||||
|
case VK_F23: return ImGuiKey_F23;
|
||||||
|
case VK_F24: return ImGuiKey_F24;
|
||||||
|
case VK_BROWSER_BACK: return ImGuiKey_AppBack;
|
||||||
|
case VK_BROWSER_FORWARD: return ImGuiKey_AppForward;
|
||||||
|
default: return ImGuiKey_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
|
||||||
|
#ifndef WM_MOUSEHWHEEL
|
||||||
|
#define WM_MOUSEHWHEEL 0x020E
|
||||||
|
#endif
|
||||||
|
#ifndef DBT_DEVNODES_CHANGED
|
||||||
|
#define DBT_DEVNODES_CHANGED 0x0007
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
||||||
|
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||||
|
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
|
||||||
|
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||||
|
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||||
|
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
|
||||||
|
// 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.
|
||||||
|
// 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.
|
||||||
|
#if 0
|
||||||
|
// Copy this line into your .cpp file to forward declare the function.
|
||||||
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages
|
||||||
|
// Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this.
|
||||||
|
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||||
|
{
|
||||||
|
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||||
|
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||||
|
return ImGuiMouseSource_Pen;
|
||||||
|
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||||
|
return ImGuiMouseSource_TouchScreen;
|
||||||
|
return ImGuiMouseSource_Mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
// Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow().
|
||||||
|
// We silently allow both context or just only backend data to be nullptr.
|
||||||
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
|
if (bd == nullptr)
|
||||||
|
return 0;
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
case WM_NCMOUSEMOVE:
|
||||||
|
{
|
||||||
|
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
||||||
|
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||||
|
const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
|
||||||
|
bd->MouseHwnd = hwnd;
|
||||||
|
if (bd->MouseTrackedArea != area)
|
||||||
|
{
|
||||||
|
TRACKMOUSEEVENT tme_cancel = { sizeof(tme_cancel), TME_CANCEL, hwnd, 0 };
|
||||||
|
TRACKMOUSEEVENT tme_track = { sizeof(tme_track), (DWORD)((area == 2) ? (TME_LEAVE | TME_NONCLIENT) : TME_LEAVE), hwnd, 0 };
|
||||||
|
if (bd->MouseTrackedArea != 0)
|
||||||
|
::TrackMouseEvent(&tme_cancel);
|
||||||
|
::TrackMouseEvent(&tme_track);
|
||||||
|
bd->MouseTrackedArea = area;
|
||||||
|
}
|
||||||
|
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
|
||||||
|
if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &mouse_pos) == FALSE) // WM_NCMOUSEMOVE are provided in absolute coordinates.
|
||||||
|
return 0;
|
||||||
|
io.AddMouseSourceEvent(mouse_source);
|
||||||
|
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case WM_MOUSELEAVE:
|
||||||
|
case WM_NCMOUSELEAVE:
|
||||||
|
{
|
||||||
|
const int area = (msg == WM_MOUSELEAVE) ? 1 : 2;
|
||||||
|
if (bd->MouseTrackedArea == area)
|
||||||
|
{
|
||||||
|
if (bd->MouseHwnd == hwnd)
|
||||||
|
bd->MouseHwnd = nullptr;
|
||||||
|
bd->MouseTrackedArea = 0;
|
||||||
|
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||||
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||||
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||||
|
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
||||||
|
{
|
||||||
|
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||||
|
int button = 0;
|
||||||
|
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
||||||
|
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||||
|
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
||||||
|
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||||
|
if (bd->MouseButtonsDown == 0 && ::GetCapture() == nullptr)
|
||||||
|
::SetCapture(hwnd);
|
||||||
|
bd->MouseButtonsDown |= 1 << button;
|
||||||
|
io.AddMouseSourceEvent(mouse_source);
|
||||||
|
io.AddMouseButtonEvent(button, true);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
case WM_RBUTTONUP:
|
||||||
|
case WM_MBUTTONUP:
|
||||||
|
case WM_XBUTTONUP:
|
||||||
|
{
|
||||||
|
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||||
|
int button = 0;
|
||||||
|
if (msg == WM_LBUTTONUP) { button = 0; }
|
||||||
|
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||||
|
if (msg == WM_MBUTTONUP) { button = 2; }
|
||||||
|
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||||
|
bd->MouseButtonsDown &= ~(1 << button);
|
||||||
|
if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
|
||||||
|
::ReleaseCapture();
|
||||||
|
io.AddMouseSourceEvent(mouse_source);
|
||||||
|
io.AddMouseButtonEvent(button, false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
io.AddMouseWheelEvent(0.0f, (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA);
|
||||||
|
return 0;
|
||||||
|
case WM_MOUSEHWHEEL:
|
||||||
|
io.AddMouseWheelEvent(-(float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0.0f);
|
||||||
|
return 0;
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
case WM_KEYUP:
|
||||||
|
case WM_SYSKEYDOWN:
|
||||||
|
case WM_SYSKEYUP:
|
||||||
|
{
|
||||||
|
const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
|
||||||
|
if (wParam < 256)
|
||||||
|
{
|
||||||
|
// Submit modifiers
|
||||||
|
ImGui_ImplWin32_UpdateKeyModifiers();
|
||||||
|
|
||||||
|
// Obtain virtual key code
|
||||||
|
// (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.)
|
||||||
|
int vk = (int)wParam;
|
||||||
|
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||||
|
vk = IM_VK_KEYPAD_ENTER;
|
||||||
|
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
|
||||||
|
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
||||||
|
|
||||||
|
// Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
|
||||||
|
if (key == ImGuiKey_PrintScreen && !is_key_down)
|
||||||
|
ImGui_ImplWin32_AddKeyEvent(key, true, vk, scancode);
|
||||||
|
|
||||||
|
// Submit key event
|
||||||
|
if (key != ImGuiKey_None)
|
||||||
|
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
|
||||||
|
|
||||||
|
// Submit individual left/right modifier events
|
||||||
|
if (vk == VK_SHIFT)
|
||||||
|
{
|
||||||
|
// Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
||||||
|
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
|
||||||
|
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
|
||||||
|
}
|
||||||
|
else if (vk == VK_CONTROL)
|
||||||
|
{
|
||||||
|
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
|
||||||
|
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
||||||
|
}
|
||||||
|
else if (vk == VK_MENU)
|
||||||
|
{
|
||||||
|
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
|
||||||
|
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case WM_SETFOCUS:
|
||||||
|
case WM_KILLFOCUS:
|
||||||
|
io.AddFocusEvent(msg == WM_SETFOCUS);
|
||||||
|
return 0;
|
||||||
|
case WM_INPUTLANGCHANGE:
|
||||||
|
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
||||||
|
return 0;
|
||||||
|
case WM_CHAR:
|
||||||
|
if (::IsWindowUnicode(hwnd))
|
||||||
|
{
|
||||||
|
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||||
|
if (wParam > 0 && wParam < 0x10000)
|
||||||
|
io.AddInputCharacterUTF16((unsigned short)wParam);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wchar_t wch = 0;
|
||||||
|
::MultiByteToWideChar(bd->KeyboardCodePage, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1);
|
||||||
|
io.AddInputCharacter(wch);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
case WM_SETCURSOR:
|
||||||
|
// This is required to restore cursor when transitioning from e.g resize borders to client area.
|
||||||
|
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
case WM_DEVICECHANGE:
|
||||||
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
if ((UINT)wParam == DBT_DEVNODES_CHANGED)
|
||||||
|
bd->WantUpdateHasGamepad = true;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
// DPI-related helpers (optional)
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
// - Use to enable DPI awareness without having to create an application manifest.
|
||||||
|
// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
|
||||||
|
// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
|
||||||
|
// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
|
||||||
|
// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
|
||||||
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
// This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable.
|
||||||
|
// ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically.
|
||||||
|
// If you are trying to implement your own backend for your own engine, you may ignore that noise.
|
||||||
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Perform our own check with RtlVerifyVersionInfo() instead of using functions from <VersionHelpers.h> as they
|
||||||
|
// require a manifest to be functional for checks above 8.1. See https://github.com/ocornut/imgui/issues/4200
|
||||||
|
static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
||||||
|
{
|
||||||
|
typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
|
||||||
|
static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = nullptr;
|
||||||
|
if (RtlVerifyVersionInfoFn == nullptr)
|
||||||
|
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
||||||
|
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
||||||
|
if (RtlVerifyVersionInfoFn == nullptr)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
RTL_OSVERSIONINFOEXW versionInfo = { };
|
||||||
|
ULONGLONG conditionMask = 0;
|
||||||
|
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
||||||
|
versionInfo.dwMajorVersion = major;
|
||||||
|
versionInfo.dwMinorVersion = minor;
|
||||||
|
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
|
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
|
return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
|
||||||
|
#define _IsWindows8OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WIN8
|
||||||
|
#define _IsWindows8Point1OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0) // _WIN32_WINNT_WINBLUE
|
||||||
|
#define _IsWindows10OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0A00), LOBYTE(0x0A00), 0) // _WIN32_WINNT_WINTHRESHOLD / _WIN32_WINNT_WIN10
|
||||||
|
|
||||||
|
#ifndef DPI_ENUMS_DECLARED
|
||||||
|
typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS;
|
||||||
|
typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE;
|
||||||
|
#endif
|
||||||
|
#ifndef _DPI_AWARENESS_CONTEXTS_
|
||||||
|
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
||||||
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3
|
||||||
|
#endif
|
||||||
|
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
||||||
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4
|
||||||
|
#endif
|
||||||
|
typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
|
||||||
|
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
|
||||||
|
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
|
||||||
|
|
||||||
|
// Helper function to enable DPI awareness without setting up a manifest
|
||||||
|
void ImGui_ImplWin32_EnableDpiAwareness()
|
||||||
|
{
|
||||||
|
if (_IsWindows10OrGreater())
|
||||||
|
{
|
||||||
|
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
||||||
|
if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext"))
|
||||||
|
{
|
||||||
|
SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_IsWindows8Point1OrGreater())
|
||||||
|
{
|
||||||
|
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||||
|
if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness"))
|
||||||
|
{
|
||||||
|
SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if _WIN32_WINNT >= 0x0600
|
||||||
|
::SetProcessDPIAware();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(NOGDI)
|
||||||
|
#pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
||||||
|
{
|
||||||
|
UINT xdpi = 96, ydpi = 96;
|
||||||
|
if (_IsWindows8Point1OrGreater())
|
||||||
|
{
|
||||||
|
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||||
|
static PFN_GetDpiForMonitor GetDpiForMonitorFn = nullptr;
|
||||||
|
if (GetDpiForMonitorFn == nullptr && shcore_dll != nullptr)
|
||||||
|
GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
|
||||||
|
if (GetDpiForMonitorFn != nullptr)
|
||||||
|
{
|
||||||
|
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||||
|
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||||
|
return xdpi / 96.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifndef NOGDI
|
||||||
|
const HDC dc = ::GetDC(nullptr);
|
||||||
|
xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
|
||||||
|
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
|
||||||
|
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||||
|
::ReleaseDC(nullptr, dc);
|
||||||
|
#endif
|
||||||
|
return xdpi / 96.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
|
||||||
|
{
|
||||||
|
HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST);
|
||||||
|
return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
// Transparency related helpers (optional)
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma comment(lib, "dwmapi") // Link with dwmapi.lib. MinGW will require linking with '-ldwmapi'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// [experimental]
|
||||||
|
// Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c
|
||||||
|
// (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW)
|
||||||
|
void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
||||||
|
{
|
||||||
|
if (!_IsWindowsVistaOrGreater())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BOOL composition;
|
||||||
|
if (FAILED(::DwmIsCompositionEnabled(&composition)) || !composition)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BOOL opaque;
|
||||||
|
DWORD color;
|
||||||
|
if (_IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque))
|
||||||
|
{
|
||||||
|
HRGN region = ::CreateRectRgn(0, 0, -1, -1);
|
||||||
|
DWM_BLURBEHIND bb = {};
|
||||||
|
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||||
|
bb.hRgnBlur = region;
|
||||||
|
bb.fEnable = TRUE;
|
||||||
|
::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
|
||||||
|
::DeleteObject(region);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DWM_BLURBEHIND bb = {};
|
||||||
|
bb.dwFlags = DWM_BB_ENABLE;
|
||||||
|
::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
53
ScreenRecoder/ImGui/imgui_impl_win32.h
Normal file
53
ScreenRecoder/ImGui/imgui_impl_win32.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
|
||||||
|
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||||
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||||
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||||
|
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||||
|
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
|
||||||
|
|
||||||
|
// Win32 message handler your application need to call.
|
||||||
|
// - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on <windows.h> from this helper.
|
||||||
|
// - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
|
||||||
|
// - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// DPI-related helpers (optional)
|
||||||
|
// - Use to enable DPI awareness without having to create an application manifest.
|
||||||
|
// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
|
||||||
|
// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
|
||||||
|
// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
|
||||||
|
// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
|
||||||
|
IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd
|
||||||
|
IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor
|
||||||
|
|
||||||
|
// Transparency related helpers (optional) [experimental]
|
||||||
|
// - Use to enable alpha compositing transparency with the desktop.
|
||||||
|
// - Use together with e.g. clearing your framebuffer with zero-alpha.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
3712
ScreenRecoder/ImGui/imgui_internal.h
Normal file
3712
ScreenRecoder/ImGui/imgui_internal.h
Normal file
File diff suppressed because it is too large
Load Diff
4451
ScreenRecoder/ImGui/imgui_tables.cpp
Normal file
4451
ScreenRecoder/ImGui/imgui_tables.cpp
Normal file
File diff suppressed because it is too large
Load Diff
10169
ScreenRecoder/ImGui/imgui_widgets.cpp
Normal file
10169
ScreenRecoder/ImGui/imgui_widgets.cpp
Normal file
File diff suppressed because it is too large
Load Diff
627
ScreenRecoder/ImGui/imstb_rectpack.h
Normal file
627
ScreenRecoder/ImGui/imstb_rectpack.h
Normal file
@ -0,0 +1,627 @@
|
|||||||
|
// [DEAR IMGUI]
|
||||||
|
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
||||||
|
// Grep for [DEAR IMGUI] to find the changes.
|
||||||
|
//
|
||||||
|
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
||||||
|
// Sean Barrett 2014
|
||||||
|
//
|
||||||
|
// Useful for e.g. packing rectangular textures into an atlas.
|
||||||
|
// Does not do rotation.
|
||||||
|
//
|
||||||
|
// Before #including,
|
||||||
|
//
|
||||||
|
// #define STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
//
|
||||||
|
// in the file that you want to have the implementation.
|
||||||
|
//
|
||||||
|
// Not necessarily the awesomest packing method, but better than
|
||||||
|
// the totally naive one in stb_truetype (which is primarily what
|
||||||
|
// this is meant to replace).
|
||||||
|
//
|
||||||
|
// Has only had a few tests run, may have issues.
|
||||||
|
//
|
||||||
|
// More docs to come.
|
||||||
|
//
|
||||||
|
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||||
|
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||||
|
//
|
||||||
|
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||||
|
//
|
||||||
|
// Please note: better rectangle packers are welcome! Please
|
||||||
|
// implement them to the same API, but with a different init
|
||||||
|
// function.
|
||||||
|
//
|
||||||
|
// Credits
|
||||||
|
//
|
||||||
|
// Library
|
||||||
|
// Sean Barrett
|
||||||
|
// Minor features
|
||||||
|
// Martins Mozeiko
|
||||||
|
// github:IntellectualKitty
|
||||||
|
//
|
||||||
|
// Bugfixes / warning fixes
|
||||||
|
// Jeremy Jaussaud
|
||||||
|
// Fabian Giesen
|
||||||
|
//
|
||||||
|
// Version history:
|
||||||
|
//
|
||||||
|
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
||||||
|
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||||
|
// 0.99 (2019-02-07) warning fixes
|
||||||
|
// 0.11 (2017-03-03) return packing success/fail result
|
||||||
|
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||||
|
// 0.09 (2016-08-27) fix compiler warnings
|
||||||
|
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||||
|
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||||
|
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||||
|
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||||
|
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||||
|
// 0.01: initial release
|
||||||
|
//
|
||||||
|
// LICENSE
|
||||||
|
//
|
||||||
|
// See end of file for license information.
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// INCLUDE SECTION
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||||
|
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||||
|
|
||||||
|
#define STB_RECT_PACK_VERSION 1
|
||||||
|
|
||||||
|
#ifdef STBRP_STATIC
|
||||||
|
#define STBRP_DEF static
|
||||||
|
#else
|
||||||
|
#define STBRP_DEF extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct stbrp_context stbrp_context;
|
||||||
|
typedef struct stbrp_node stbrp_node;
|
||||||
|
typedef struct stbrp_rect stbrp_rect;
|
||||||
|
|
||||||
|
typedef int stbrp_coord;
|
||||||
|
|
||||||
|
#define STBRP__MAXVAL 0x7fffffff
|
||||||
|
// Mostly for internal use, but this is the maximum supported coordinate value.
|
||||||
|
|
||||||
|
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||||
|
// Assign packed locations to rectangles. The rectangles are of type
|
||||||
|
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||||
|
// are 'num_rects' many of them.
|
||||||
|
//
|
||||||
|
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||||
|
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||||
|
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||||
|
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||||
|
// have the 'was_packed' flag set to 0.
|
||||||
|
//
|
||||||
|
// You should not try to access the 'rects' array from another thread
|
||||||
|
// while this function is running, as the function temporarily reorders
|
||||||
|
// the array while it executes.
|
||||||
|
//
|
||||||
|
// To pack into another rectangle, you need to call stbrp_init_target
|
||||||
|
// again. To continue packing into the same rectangle, you can call
|
||||||
|
// this function again. Calling this multiple times with multiple rect
|
||||||
|
// arrays will probably produce worse packing results than calling it
|
||||||
|
// a single time with the full rectangle array, but the option is
|
||||||
|
// available.
|
||||||
|
//
|
||||||
|
// The function returns 1 if all of the rectangles were successfully
|
||||||
|
// packed and 0 otherwise.
|
||||||
|
|
||||||
|
struct stbrp_rect
|
||||||
|
{
|
||||||
|
// reserved for your use:
|
||||||
|
int id;
|
||||||
|
|
||||||
|
// input:
|
||||||
|
stbrp_coord w, h;
|
||||||
|
|
||||||
|
// output:
|
||||||
|
stbrp_coord x, y;
|
||||||
|
int was_packed; // non-zero if valid packing
|
||||||
|
|
||||||
|
}; // 16 bytes, nominally
|
||||||
|
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||||
|
// Initialize a rectangle packer to:
|
||||||
|
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||||
|
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||||
|
//
|
||||||
|
// You must call this function every time you start packing into a new target.
|
||||||
|
//
|
||||||
|
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||||
|
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||||
|
// the call (or calls) finish.
|
||||||
|
//
|
||||||
|
// Note: to guarantee best results, either:
|
||||||
|
// 1. make sure 'num_nodes' >= 'width'
|
||||||
|
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||||
|
//
|
||||||
|
// If you don't do either of the above things, widths will be quantized to multiples
|
||||||
|
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||||
|
//
|
||||||
|
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||||
|
// may run out of temporary storage and be unable to pack some rectangles.
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||||
|
// Optionally call this function after init but before doing any packing to
|
||||||
|
// change the handling of the out-of-temp-memory scenario, described above.
|
||||||
|
// If you call init again, this will be reset to the default (false).
|
||||||
|
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||||
|
// Optionally select which packing heuristic the library should use. Different
|
||||||
|
// heuristics will produce better/worse results for different data sets.
|
||||||
|
// If you call init again, this will be reset to the default.
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STBRP_HEURISTIC_Skyline_default=0,
|
||||||
|
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||||
|
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// the details of the following structures don't matter to you, but they must
|
||||||
|
// be visible so you can handle the memory allocations for them
|
||||||
|
|
||||||
|
struct stbrp_node
|
||||||
|
{
|
||||||
|
stbrp_coord x,y;
|
||||||
|
stbrp_node *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stbrp_context
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int align;
|
||||||
|
int init_mode;
|
||||||
|
int heuristic;
|
||||||
|
int num_nodes;
|
||||||
|
stbrp_node *active_head;
|
||||||
|
stbrp_node *free_head;
|
||||||
|
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// IMPLEMENTATION SECTION
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
#ifndef STBRP_SORT
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define STBRP_SORT qsort
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STBRP_ASSERT
|
||||||
|
#include <assert.h>
|
||||||
|
#define STBRP_ASSERT assert
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define STBRP__NOTUSED(v) (void)(v)
|
||||||
|
#define STBRP__CDECL __cdecl
|
||||||
|
#else
|
||||||
|
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||||
|
#define STBRP__CDECL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STBRP__INIT_skyline = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||||
|
{
|
||||||
|
switch (context->init_mode) {
|
||||||
|
case STBRP__INIT_skyline:
|
||||||
|
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||||
|
context->heuristic = heuristic;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
STBRP_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||||
|
{
|
||||||
|
if (allow_out_of_mem)
|
||||||
|
// if it's ok to run out of memory, then don't bother aligning them;
|
||||||
|
// this gives better packing, but may fail due to OOM (even though
|
||||||
|
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||||
|
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||||
|
context->align = 1;
|
||||||
|
else {
|
||||||
|
// if it's not ok to run out of memory, then quantize the widths
|
||||||
|
// so that num_nodes is always enough nodes.
|
||||||
|
//
|
||||||
|
// I.e. num_nodes * align >= width
|
||||||
|
// align >= width / num_nodes
|
||||||
|
// align = ceil(width/num_nodes)
|
||||||
|
|
||||||
|
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i < num_nodes-1; ++i)
|
||||||
|
nodes[i].next = &nodes[i+1];
|
||||||
|
nodes[i].next = NULL;
|
||||||
|
context->init_mode = STBRP__INIT_skyline;
|
||||||
|
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||||
|
context->free_head = &nodes[0];
|
||||||
|
context->active_head = &context->extra[0];
|
||||||
|
context->width = width;
|
||||||
|
context->height = height;
|
||||||
|
context->num_nodes = num_nodes;
|
||||||
|
stbrp_setup_allow_out_of_mem(context, 0);
|
||||||
|
|
||||||
|
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||||
|
context->extra[0].x = 0;
|
||||||
|
context->extra[0].y = 0;
|
||||||
|
context->extra[0].next = &context->extra[1];
|
||||||
|
context->extra[1].x = (stbrp_coord) width;
|
||||||
|
context->extra[1].y = (1<<30);
|
||||||
|
context->extra[1].next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find minimum y position if it starts at x1
|
||||||
|
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||||
|
{
|
||||||
|
stbrp_node *node = first;
|
||||||
|
int x1 = x0 + width;
|
||||||
|
int min_y, visited_width, waste_area;
|
||||||
|
|
||||||
|
STBRP__NOTUSED(c);
|
||||||
|
|
||||||
|
STBRP_ASSERT(first->x <= x0);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// skip in case we're past the node
|
||||||
|
while (node->next->x <= x0)
|
||||||
|
++node;
|
||||||
|
#else
|
||||||
|
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STBRP_ASSERT(node->x <= x0);
|
||||||
|
|
||||||
|
min_y = 0;
|
||||||
|
waste_area = 0;
|
||||||
|
visited_width = 0;
|
||||||
|
while (node->x < x1) {
|
||||||
|
if (node->y > min_y) {
|
||||||
|
// raise min_y higher.
|
||||||
|
// we've accounted for all waste up to min_y,
|
||||||
|
// but we'll now add more waste for everything we've visted
|
||||||
|
waste_area += visited_width * (node->y - min_y);
|
||||||
|
min_y = node->y;
|
||||||
|
// the first time through, visited_width might be reduced
|
||||||
|
if (node->x < x0)
|
||||||
|
visited_width += node->next->x - x0;
|
||||||
|
else
|
||||||
|
visited_width += node->next->x - node->x;
|
||||||
|
} else {
|
||||||
|
// add waste area
|
||||||
|
int under_width = node->next->x - node->x;
|
||||||
|
if (under_width + visited_width > width)
|
||||||
|
under_width = width - visited_width;
|
||||||
|
waste_area += under_width * (min_y - node->y);
|
||||||
|
visited_width += under_width;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pwaste = waste_area;
|
||||||
|
return min_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x,y;
|
||||||
|
stbrp_node **prev_link;
|
||||||
|
} stbrp__findresult;
|
||||||
|
|
||||||
|
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||||
|
{
|
||||||
|
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||||
|
stbrp__findresult fr;
|
||||||
|
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||||
|
|
||||||
|
// align to multiple of c->align
|
||||||
|
width = (width + c->align - 1);
|
||||||
|
width -= width % c->align;
|
||||||
|
STBRP_ASSERT(width % c->align == 0);
|
||||||
|
|
||||||
|
// if it can't possibly fit, bail immediately
|
||||||
|
if (width > c->width || height > c->height) {
|
||||||
|
fr.prev_link = NULL;
|
||||||
|
fr.x = fr.y = 0;
|
||||||
|
return fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = c->active_head;
|
||||||
|
prev = &c->active_head;
|
||||||
|
while (node->x + width <= c->width) {
|
||||||
|
int y,waste;
|
||||||
|
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||||
|
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||||
|
// bottom left
|
||||||
|
if (y < best_y) {
|
||||||
|
best_y = y;
|
||||||
|
best = prev;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// best-fit
|
||||||
|
if (y + height <= c->height) {
|
||||||
|
// can only use it if it first vertically
|
||||||
|
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||||
|
best_y = y;
|
||||||
|
best_waste = waste;
|
||||||
|
best = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = &node->next;
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||||
|
|
||||||
|
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||||
|
//
|
||||||
|
// e.g, if fitting
|
||||||
|
//
|
||||||
|
// ____________________
|
||||||
|
// |____________________|
|
||||||
|
//
|
||||||
|
// into
|
||||||
|
//
|
||||||
|
// | |
|
||||||
|
// | ____________|
|
||||||
|
// |____________|
|
||||||
|
//
|
||||||
|
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||||
|
//
|
||||||
|
// This makes BF take about 2x the time
|
||||||
|
|
||||||
|
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||||
|
tail = c->active_head;
|
||||||
|
node = c->active_head;
|
||||||
|
prev = &c->active_head;
|
||||||
|
// find first node that's admissible
|
||||||
|
while (tail->x < width)
|
||||||
|
tail = tail->next;
|
||||||
|
while (tail) {
|
||||||
|
int xpos = tail->x - width;
|
||||||
|
int y,waste;
|
||||||
|
STBRP_ASSERT(xpos >= 0);
|
||||||
|
// find the left position that matches this
|
||||||
|
while (node->next->x <= xpos) {
|
||||||
|
prev = &node->next;
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||||
|
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||||
|
if (y + height <= c->height) {
|
||||||
|
if (y <= best_y) {
|
||||||
|
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||||
|
best_x = xpos;
|
||||||
|
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
|
||||||
|
best_y = y;
|
||||||
|
best_waste = waste;
|
||||||
|
best = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tail = tail->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fr.prev_link = best;
|
||||||
|
fr.x = best_x;
|
||||||
|
fr.y = best_y;
|
||||||
|
return fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||||
|
{
|
||||||
|
// find best position according to heuristic
|
||||||
|
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||||
|
stbrp_node *node, *cur;
|
||||||
|
|
||||||
|
// bail if:
|
||||||
|
// 1. it failed
|
||||||
|
// 2. the best node doesn't fit (we don't always check this)
|
||||||
|
// 3. we're out of memory
|
||||||
|
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||||
|
res.prev_link = NULL;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// on success, create new node
|
||||||
|
node = context->free_head;
|
||||||
|
node->x = (stbrp_coord) res.x;
|
||||||
|
node->y = (stbrp_coord) (res.y + height);
|
||||||
|
|
||||||
|
context->free_head = node->next;
|
||||||
|
|
||||||
|
// insert the new node into the right starting point, and
|
||||||
|
// let 'cur' point to the remaining nodes needing to be
|
||||||
|
// stiched back in
|
||||||
|
|
||||||
|
cur = *res.prev_link;
|
||||||
|
if (cur->x < res.x) {
|
||||||
|
// preserve the existing one, so start testing with the next one
|
||||||
|
stbrp_node *next = cur->next;
|
||||||
|
cur->next = node;
|
||||||
|
cur = next;
|
||||||
|
} else {
|
||||||
|
*res.prev_link = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// from here, traverse cur and free the nodes, until we get to one
|
||||||
|
// that shouldn't be freed
|
||||||
|
while (cur->next && cur->next->x <= res.x + width) {
|
||||||
|
stbrp_node *next = cur->next;
|
||||||
|
// move the current node to the free list
|
||||||
|
cur->next = context->free_head;
|
||||||
|
context->free_head = cur;
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stitch the list back in
|
||||||
|
node->next = cur;
|
||||||
|
|
||||||
|
if (cur->x < res.x + width)
|
||||||
|
cur->x = (stbrp_coord) (res.x + width);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
cur = context->active_head;
|
||||||
|
while (cur->x < context->width) {
|
||||||
|
STBRP_ASSERT(cur->x < cur->next->x);
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
STBRP_ASSERT(cur->next == NULL);
|
||||||
|
|
||||||
|
{
|
||||||
|
int count=0;
|
||||||
|
cur = context->active_head;
|
||||||
|
while (cur) {
|
||||||
|
cur = cur->next;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
cur = context->free_head;
|
||||||
|
while (cur) {
|
||||||
|
cur = cur->next;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
STBRP_ASSERT(count == context->num_nodes+2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||||
|
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||||
|
if (p->h > q->h)
|
||||||
|
return -1;
|
||||||
|
if (p->h < q->h)
|
||||||
|
return 1;
|
||||||
|
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||||
|
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||||
|
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||||
|
}
|
||||||
|
|
||||||
|
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||||
|
{
|
||||||
|
int i, all_rects_packed = 1;
|
||||||
|
|
||||||
|
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||||
|
for (i=0; i < num_rects; ++i) {
|
||||||
|
rects[i].was_packed = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort according to heuristic
|
||||||
|
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||||
|
|
||||||
|
for (i=0; i < num_rects; ++i) {
|
||||||
|
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||||
|
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||||
|
} else {
|
||||||
|
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||||
|
if (fr.prev_link) {
|
||||||
|
rects[i].x = (stbrp_coord) fr.x;
|
||||||
|
rects[i].y = (stbrp_coord) fr.y;
|
||||||
|
} else {
|
||||||
|
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsort
|
||||||
|
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||||
|
|
||||||
|
// set was_packed flags and all_rects_packed status
|
||||||
|
for (i=0; i < num_rects; ++i) {
|
||||||
|
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||||
|
if (!rects[i].was_packed)
|
||||||
|
all_rects_packed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the all_rects_packed status
|
||||||
|
return all_rects_packed;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This software is available under 2 licenses -- choose whichever you prefer.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE A - MIT License
|
||||||
|
Copyright (c) 2017 Sean Barrett
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||||
|
software, either in source code form or as a compiled binary, for any purpose,
|
||||||
|
commercial or non-commercial, and by any means.
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||||
|
software dedicate any and all copyright interest in the software to the public
|
||||||
|
domain. We make this dedication for the benefit of the public at large and to
|
||||||
|
the detriment of our heirs and successors. We intend this dedication to be an
|
||||||
|
overt act of relinquishment in perpetuity of all present and future rights to
|
||||||
|
this software under copyright law.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*/
|
1441
ScreenRecoder/ImGui/imstb_textedit.h
Normal file
1441
ScreenRecoder/ImGui/imstb_textedit.h
Normal file
File diff suppressed because it is too large
Load Diff
5085
ScreenRecoder/ImGui/imstb_truetype.h
Normal file
5085
ScreenRecoder/ImGui/imstb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
191
ScreenRecoder/ImHelper.cpp
Normal file
191
ScreenRecoder/ImHelper.cpp
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
#include "ImHelper.h"
|
||||||
|
#include "Utils/Utils.h"
|
||||||
|
#include "d3dx11.h"
|
||||||
|
#pragma comment(lib,"D3Dx11.lib")
|
||||||
|
void ImDrawLine(float x1, float y1, float x2, float y2, ImU32 clr, float thickness)
|
||||||
|
{
|
||||||
|
ImGui::GetBackgroundDrawList()->AddLine(ImVec2(x1, y1), ImVec2(x2, y2), clr, thickness);
|
||||||
|
}
|
||||||
|
void ImDrawCircle(float x, float y, float rad, ImU32 clr, float thickness)
|
||||||
|
{
|
||||||
|
int line = rad / 2;
|
||||||
|
ImGui::GetBackgroundDrawList()->AddCircle(ImVec2(x, y), rad, clr, line, thickness);
|
||||||
|
}
|
||||||
|
void ImDrawRect(float x, float y, float width, float height, ImU32 clr, float thickness)
|
||||||
|
{
|
||||||
|
ImVec2 min = ImVec2(x, y);
|
||||||
|
ImVec2 max = ImVec2(x + width, y + height);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddRect(min, max, clr, 0.0F, -1, thickness);
|
||||||
|
}
|
||||||
|
void ImFillRect(float x, float y, float width, float height, ImU32 clr)
|
||||||
|
{
|
||||||
|
ImVec2 min = ImVec2(x, y);
|
||||||
|
ImVec2 max = ImVec2(x + width, y + height);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddRectFilled(min, max, clr, 0.0F, -1);
|
||||||
|
}
|
||||||
|
void ImDrawString(ImFont* font, float sizez, float x, float y, ImU32 color, const char* message, ...)
|
||||||
|
{
|
||||||
|
char output[1024] = {};
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
vsprintf_s(output, message, args);
|
||||||
|
va_end(args);
|
||||||
|
auto coord = ImVec2(x, y);
|
||||||
|
auto size = ImGui::CalcTextSize(output);
|
||||||
|
auto coord_out = ImVec2{ coord.x + 1.f, coord.y + 1.f };
|
||||||
|
ImColor black = ImColor(0, 0, 0);
|
||||||
|
auto _msg = Convert::AnsiToUtf8(message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x - 1, y), black, _msg.c_str());
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y - 1), black, _msg.c_str());
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x + 1, y), black, _msg.c_str());
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y + 1), black, _msg.c_str());
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y), color, _msg.c_str());
|
||||||
|
}
|
||||||
|
void ImDrawStringCenter(ImFont* font, float sizez, float x, float y, ImU32 color, const char* message, ...)
|
||||||
|
{
|
||||||
|
char output[1024] = {};
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
vsprintf_s(output, message, args);
|
||||||
|
va_end(args);
|
||||||
|
auto coord = ImVec2(x, y);
|
||||||
|
auto size = ImGui::CalcTextSize(output);
|
||||||
|
auto coord_out = ImVec2{ coord.x + 1.f, coord.y + 1.f };
|
||||||
|
ImColor black = ImColor(0, 0, 0);
|
||||||
|
x -= (size.x * 0.5f);
|
||||||
|
y -= (size.y * 0.5f);
|
||||||
|
auto _msg = Convert::AnsiToUtf8(message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x - 1, y), black, _msg.c_str());
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y - 1), black, _msg.c_str());
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x + 1, y), black, _msg.c_str());
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y + 1), black, _msg.c_str());
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y), color, _msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImDrawStringU8(ImFont* font, float sizez, float x, float y, ImU32 color, const char* message, ...)
|
||||||
|
{
|
||||||
|
|
||||||
|
char output[1024] = {};
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
vsprintf_s(output, message, args);
|
||||||
|
va_end(args);
|
||||||
|
auto coord = ImVec2(x, y);
|
||||||
|
auto size = ImGui::CalcTextSize(output);
|
||||||
|
auto coord_out = ImVec2{ coord.x + 1.f, coord.y + 1.f };
|
||||||
|
ImColor black = ImColor(0, 0, 0);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x - 1, y), black, message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y - 1), black, message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x + 1, y), black, message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y + 1), black, message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y), color, message);
|
||||||
|
}
|
||||||
|
void ImDrawStringCenterU8(ImFont* font, float sizez, float x, float y, ImU32 color, const char* message, ...)
|
||||||
|
{
|
||||||
|
char output[1024] = {};
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
vsprintf_s(output, message, args);
|
||||||
|
va_end(args);
|
||||||
|
auto coord = ImVec2(x, y);
|
||||||
|
auto size = ImGui::CalcTextSize(output);
|
||||||
|
auto coord_out = ImVec2{ coord.x + 1.f, coord.y + 1.f };
|
||||||
|
ImColor black = ImColor(0, 0, 0);
|
||||||
|
x -= (size.x * 0.5f);
|
||||||
|
y -= (size.y * 0.5f);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x - 1, y), black, message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y - 1), black, message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x + 1, y), black, message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y + 1), black, message);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(font, sizez, ImVec2(x, y), color, message);
|
||||||
|
}
|
||||||
|
ID3D11Texture2D* LoadTextureFromMem(ID3D11Device* d3dDevice, const unsigned char* mem, int size)
|
||||||
|
{
|
||||||
|
ID3D11Texture2D* pFontTextureView = NULL;
|
||||||
|
D3DX11_IMAGE_LOAD_INFO loadInfo{};
|
||||||
|
HRESULT hr = D3DX11CreateTextureFromMemory(d3dDevice, mem, size, &loadInfo, NULL, (ID3D11Resource**)&pFontTextureView, NULL);
|
||||||
|
if (hr != S_OK)
|
||||||
|
return NULL;
|
||||||
|
return pFontTextureView;
|
||||||
|
}
|
||||||
|
ID3D11Texture2D* LoadTextureFromMem(const unsigned char* mem, int size)
|
||||||
|
{
|
||||||
|
ID3D11Device* d3dDevice = *(ID3D11Device**)ImGui::GetIO().BackendRendererUserData;
|
||||||
|
ID3D11Texture2D* pFontTextureView = NULL;
|
||||||
|
D3DX11_IMAGE_LOAD_INFO loadInfo{};
|
||||||
|
HRESULT hr = D3DX11CreateTextureFromMemory(d3dDevice, mem, size, &loadInfo, NULL, (ID3D11Resource**)&pFontTextureView, NULL);
|
||||||
|
if (hr != S_OK)
|
||||||
|
return NULL;
|
||||||
|
return pFontTextureView;
|
||||||
|
}
|
||||||
|
ID3D11ShaderResourceView* ToShaderResourceView(ID3D11Texture2D* texture)
|
||||||
|
{
|
||||||
|
ID3D11Device* d3dDevice = *(ID3D11Device**)ImGui::GetIO().BackendRendererUserData;
|
||||||
|
ID3D11ShaderResourceView* pView = NULL;
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC loadInfo = {};
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC dec{};
|
||||||
|
texture->GetDesc(&dec);
|
||||||
|
|
||||||
|
loadInfo.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
loadInfo.Format = dec.Format;
|
||||||
|
loadInfo.Texture2D.MostDetailedMip = 0;
|
||||||
|
loadInfo.Texture2D.MipLevels = dec.MipLevels;
|
||||||
|
HRESULT hr = d3dDevice->CreateShaderResourceView(texture, &loadInfo, &pView);
|
||||||
|
if (hr != S_OK)
|
||||||
|
return NULL;
|
||||||
|
return pView;
|
||||||
|
}
|
||||||
|
ID3D11ShaderResourceView* ToShaderResourceView(ID3D11Device* d3dDevice, ID3D11Texture2D* texture)
|
||||||
|
{
|
||||||
|
ID3D11ShaderResourceView* pView = NULL;
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC loadInfo = {};
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC dec{};
|
||||||
|
texture->GetDesc(&dec);
|
||||||
|
|
||||||
|
loadInfo.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
loadInfo.Format = dec.Format;
|
||||||
|
loadInfo.Texture2D.MostDetailedMip = 0;
|
||||||
|
loadInfo.Texture2D.MipLevels = dec.MipLevels;
|
||||||
|
HRESULT hr = d3dDevice->CreateShaderResourceView(texture, &loadInfo, &pView);
|
||||||
|
if (hr != S_OK)
|
||||||
|
return NULL;
|
||||||
|
return pView;
|
||||||
|
}
|
||||||
|
ID3D11ShaderResourceView* LoadImageFromMem(const unsigned char* mem, int size)
|
||||||
|
{
|
||||||
|
ID3D11Device* d3dDevice = *(ID3D11Device**)ImGui::GetIO().BackendRendererUserData;
|
||||||
|
ID3D11ShaderResourceView* pView = NULL;
|
||||||
|
D3DX11_IMAGE_LOAD_INFO loadInfo;
|
||||||
|
ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO));
|
||||||
|
loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
loadInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
loadInfo.MipLevels = D3DX11_DEFAULT;
|
||||||
|
loadInfo.MipFilter = D3DX11_FILTER_LINEAR;
|
||||||
|
HRESULT hr = D3DX11CreateShaderResourceViewFromMemory(d3dDevice, mem, size, &loadInfo, NULL, &pView, NULL);
|
||||||
|
if (hr != S_OK)
|
||||||
|
return NULL;
|
||||||
|
return pView;
|
||||||
|
}
|
||||||
|
ID3D11ShaderResourceView* LoadImageFromTexture(ID3D11Texture2D* pTexture2D)
|
||||||
|
{
|
||||||
|
ID3D11Device* d3dDevice = *(ID3D11Device**)ImGui::GetIO().BackendRendererUserData;
|
||||||
|
D3D11_TEXTURE2D_DESC dec{};
|
||||||
|
pTexture2D->GetDesc(&dec);
|
||||||
|
ID3D11ShaderResourceView* pView = NULL;
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||||
|
srvDesc.Format = dec.Format;
|
||||||
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||||
|
srvDesc.Texture2D.MipLevels = dec.MipLevels;
|
||||||
|
HRESULT hr = d3dDevice->CreateShaderResourceView(pTexture2D, &srvDesc, &pView);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return NULL;
|
||||||
|
return pView;
|
||||||
|
}
|
||||||
|
void ImImage(ID3D11ShaderResourceView* img, ImVec2 location, ImVec2 size)
|
||||||
|
{
|
||||||
|
ImGui::GetBackgroundDrawList()->AddImage(img, location, size);
|
||||||
|
}
|
28
ScreenRecoder/ImHelper.h
Normal file
28
ScreenRecoder/ImHelper.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
#include "imgui/imgui_impl_win32.h"
|
||||||
|
#include "imgui/imgui_impl_dx11.h"
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
|
struct ResourceView
|
||||||
|
{
|
||||||
|
ID3D11ShaderResourceView* view;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
};
|
||||||
|
void ImDrawLine(float x1, float y1, float x2, float y2, ImU32 clr, float thickness = 1.0f);
|
||||||
|
void ImDrawCircle(float x, float y, float rad, ImU32 clr, float thickness);
|
||||||
|
void ImDrawRect(float x, float y, float width, float height, ImU32 clr, float thickness);
|
||||||
|
void ImFillRect(float x, float y, float width, float height, ImU32 clr);
|
||||||
|
void ImDrawString(ImFont* font, float sizez, float x, float y, ImU32 color, const char* message, ...);
|
||||||
|
void ImDrawStringCenter(ImFont* font, float sizez, float x, float y, ImU32 color, const char* message, ...);
|
||||||
|
void ImDrawStringU8(ImFont* font, float sizez, float x, float y, ImU32 color, const char* message, ...);
|
||||||
|
void ImDrawStringCenterU8(ImFont* font, float sizez, float x, float y, ImU32 color, const char* message, ...);
|
||||||
|
ID3D11Texture2D* LoadTextureFromMem(ID3D11Device* d3dDevice, const unsigned char* mem, int size);
|
||||||
|
ID3D11Texture2D* LoadTextureFromMem(const unsigned char* mem, int size);
|
||||||
|
ID3D11ShaderResourceView* ToShaderResourceView(ID3D11Device* d3dDevice, ID3D11Texture2D* texture);
|
||||||
|
ID3D11ShaderResourceView* ToShaderResourceView(ID3D11Texture2D* texture);
|
||||||
|
ID3D11ShaderResourceView* LoadImageFromMem(const unsigned char* mem, int size);
|
||||||
|
ID3D11ShaderResourceView* LoadImageFromTexture(ID3D11Texture2D* pTexture2D);
|
||||||
|
void ImImage(ID3D11ShaderResourceView* img, ImVec2 location, ImVec2 size);
|
||||||
|
|
18
ScreenRecoder/List.natvis
Normal file
18
ScreenRecoder/List.natvis
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||||
|
<Type Name="List<*>">
|
||||||
|
<DisplayString>Count = {_size}</DisplayString>
|
||||||
|
<Expand>
|
||||||
|
<Item Name="[Count]">_size</Item>
|
||||||
|
<Item Name="[Capacity]">_capacity</Item>
|
||||||
|
<Synthetic Name="Items">
|
||||||
|
<Expand>
|
||||||
|
<ArrayItems>
|
||||||
|
<Size>_size</Size>
|
||||||
|
<ValuePointer>_data</ValuePointer>
|
||||||
|
</ArrayItems>
|
||||||
|
</Expand>
|
||||||
|
</Synthetic>
|
||||||
|
</Expand>
|
||||||
|
</Type>
|
||||||
|
</AutoVisualizer>
|
588
ScreenRecoder/ScreenRecoder.cpp
Normal file
588
ScreenRecoder/ScreenRecoder.cpp
Normal file
@ -0,0 +1,588 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
#include "Graphics/Graphics.h"
|
||||||
|
#include "Utils/Utils.h"
|
||||||
|
#include "Media/H264Encoder.h"
|
||||||
|
#include "DXGIDuplicator.h"
|
||||||
|
|
||||||
|
#include "ImGui/imgui.h"
|
||||||
|
#include "imgui/imgui_impl_win32.h"
|
||||||
|
#include "imgui/imgui_impl_dx11.h"
|
||||||
|
#include "ImHelper.h"
|
||||||
|
#include "CursorData.h"
|
||||||
|
|
||||||
|
#pragma comment(lib, "d3d11.lib")
|
||||||
|
#pragma comment(lib, "d3dcompiler.lib")
|
||||||
|
|
||||||
|
#pragma comment(lib, "d3d11.lib")
|
||||||
|
#pragma comment(lib, "d3dcompiler.lib")
|
||||||
|
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
|
||||||
|
|
||||||
|
#define u8s(x) reinterpret_cast<const char*>(u8##x)
|
||||||
|
|
||||||
|
|
||||||
|
HWND hwnd = NULL;
|
||||||
|
ID3D11Device* pD3DDevice_Duplicator = nullptr;
|
||||||
|
ID3D11DeviceContext* pContext_Duplicator = nullptr;
|
||||||
|
ID3D11Device* g_pd3dDevice = NULL;
|
||||||
|
ID3D11DeviceContext* g_pImmediateContext = NULL;
|
||||||
|
ID3D11RenderTargetView* g_pRenderTargetView = NULL;
|
||||||
|
IDXGISwapChain* g_pSwapChain = NULL;
|
||||||
|
DXGIDuplicator* duplicator = NULL;
|
||||||
|
ID3D11Texture2D* desktopTexture2D = NULL;
|
||||||
|
IWICBitmap* WIC = NULL;
|
||||||
|
//鼠标样式表
|
||||||
|
std::vector <Tuple<HANDLE, const CursorDefine&>> CURSOR_DATA = std::vector<Tuple<HANDLE, const CursorDefine&>>();
|
||||||
|
#define GENERATE_CURSOR_DATA(d) CURSOR_DATA.push_back(Tuple<HANDLE, const CursorDefine&>(LoadCursor(NULL,MAKEINTRESOURCE(d)), _CURSOR_##d))
|
||||||
|
|
||||||
|
LONGLONG StartTime = 0;
|
||||||
|
|
||||||
|
//是否正在录制
|
||||||
|
bool _CaptureFrames = false;
|
||||||
|
//是否录制音频
|
||||||
|
bool captureSound = true;
|
||||||
|
//
|
||||||
|
int FPS = 25;
|
||||||
|
|
||||||
|
std::wstring MP4_PATH = L"./output.mp4";
|
||||||
|
//系统音频输出捕获对象
|
||||||
|
AudioCapture* _audioCap = NULL;
|
||||||
|
//H264编码对象
|
||||||
|
H264Encoder* _encoder = NULL;
|
||||||
|
//音频数据缓存
|
||||||
|
BYTE _buffer_Audio[0x40000]{};
|
||||||
|
//空白音频
|
||||||
|
BYTE _zero_buffer_Audio[38400]{};
|
||||||
|
|
||||||
|
//码率(影响视频质量和文件大小)
|
||||||
|
int VIDEOBITRATE = 0;
|
||||||
|
const char* VIDEOBITRATE_Names[] =
|
||||||
|
{
|
||||||
|
"4M",
|
||||||
|
"8M",
|
||||||
|
"16M",
|
||||||
|
"32M",
|
||||||
|
"64M",
|
||||||
|
"128M",
|
||||||
|
"256M"
|
||||||
|
};
|
||||||
|
const int VIDEOBITRATE_Values[] =
|
||||||
|
{
|
||||||
|
4000000,
|
||||||
|
8000000,
|
||||||
|
16000000,
|
||||||
|
32000000,
|
||||||
|
64000000,
|
||||||
|
128000000,
|
||||||
|
256000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
DWORD capture_AudioThread(LPVOID lpThreadParameter)
|
||||||
|
{
|
||||||
|
AudioCapture* _audioCap = (AudioCapture*)lpThreadParameter;
|
||||||
|
while (_CaptureFrames)
|
||||||
|
{
|
||||||
|
UINT32 bufferSize = 0;
|
||||||
|
LONGLONG duration = 0;
|
||||||
|
auto hr = _audioCap->Capture(_buffer_Audio, &bufferSize, &duration);
|
||||||
|
if (SUCCEEDED(hr) && bufferSize > 0)
|
||||||
|
_encoder->AddAudioFrame(_buffer_Audio, bufferSize, duration);
|
||||||
|
else
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DWORD captureThread(LPVOID lpThreadParameter)
|
||||||
|
{
|
||||||
|
ID3D11Texture2D* cnv = NULL;
|
||||||
|
int screenWidth = duplicator->Width;
|
||||||
|
int screenHeight = duplicator->Height;
|
||||||
|
|
||||||
|
WIC = Factory::CreateWICBitmap(duplicator->Width, duplicator->Height);
|
||||||
|
_audioCap = new AudioCapture();
|
||||||
|
|
||||||
|
//mp4编码对象
|
||||||
|
_encoder = new H264Encoder(MP4_PATH, screenWidth, screenHeight, FPS, VIDEOBITRATE_Values[VIDEOBITRATE]);
|
||||||
|
|
||||||
|
//设置流音频格式
|
||||||
|
_encoder->SetCurrentAudioType(_audioCap->GetMediaType());
|
||||||
|
|
||||||
|
//开始
|
||||||
|
_encoder->Begin();
|
||||||
|
_audioCap->Start();
|
||||||
|
int currFrame = 0;
|
||||||
|
auto startTime = std::chrono::high_resolution_clock::now();
|
||||||
|
StartTime = GetTickCount64();
|
||||||
|
CreateThread(
|
||||||
|
NULL, NULL, capture_AudioThread, _audioCap, NULL, NULL
|
||||||
|
);
|
||||||
|
while (_CaptureFrames)
|
||||||
|
{
|
||||||
|
HRESULT hr = duplicator->GetDesktopFrame(desktopTexture2D);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
WICRect lockRect = { 0, 0, screenWidth, screenHeight };
|
||||||
|
IWICBitmapLock* pLock = NULL;
|
||||||
|
hr = WIC->Lock(&lockRect, WICBitmapLockWrite, &pLock);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
UINT cbBufferSize = 0;
|
||||||
|
BYTE* pPixels = NULL;
|
||||||
|
hr = pLock->GetDataPointer(&cbBufferSize, &pPixels);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
//转换一下格式,否则Map失败(事实上是为了将GPU内存Map到了CPU内存中做准备转换后的对象具备了D3D11_USAGE_STAGING)
|
||||||
|
cnv = duplicator->ConvertFormat(desktopTexture2D, DXGI_FORMAT_B8G8R8A8_UNORM);
|
||||||
|
BYTE* buffer = (BYTE*)duplicator->MapBuffer(cnv);
|
||||||
|
int dst_rowpitch = screenWidth * 4;
|
||||||
|
for (int h = 0; h < screenHeight; h++) {
|
||||||
|
memcpy(pPixels + h * dst_rowpitch, buffer + ((screenHeight - (h + 1)) * dst_rowpitch), dst_rowpitch);
|
||||||
|
}
|
||||||
|
duplicator->UnMapBuffer(cnv);
|
||||||
|
#pragma region 绘制鼠标光标
|
||||||
|
uint32_t* pixels = (uint32_t*)pPixels;
|
||||||
|
auto _setpixel = [&](int xx, int yy, bool mdown)
|
||||||
|
{
|
||||||
|
yy = screenHeight - (yy + 1);
|
||||||
|
if (xx < screenWidth && yy < screenHeight)
|
||||||
|
{
|
||||||
|
uint32_t oldC = pixels[(yy * screenWidth) + xx];
|
||||||
|
if (mdown)
|
||||||
|
pixels[(yy * screenWidth) + xx] = RGB(0, 0, 255);
|
||||||
|
else
|
||||||
|
pixels[(yy * screenWidth) + xx] = RGB(255 - GetRValue(oldC), 255 - GetGValue(oldC), 255 - GetBValue(oldC));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto drawMouseArrow = [&](int startX, int startY, bool mdown, const CursorDefine& cursorPattern)
|
||||||
|
{
|
||||||
|
if (cursorPattern.Center)
|
||||||
|
{
|
||||||
|
startX -= 16;
|
||||||
|
startY -= 16;
|
||||||
|
}
|
||||||
|
for (int y = 0; y < 32; ++y)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < 32; ++x)
|
||||||
|
{
|
||||||
|
if (cursorPattern.Data[y] & (1 << (31 - x)))
|
||||||
|
{
|
||||||
|
_setpixel(startX + x, startY + y, mdown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
bool mdown = GetAsyncKeyState(VK_LBUTTON) & 0x8000;
|
||||||
|
CURSORINFO cursorInfo = { sizeof(CURSORINFO) };
|
||||||
|
GetCursorInfo(&cursorInfo);
|
||||||
|
HCURSOR hCursor = cursorInfo.hCursor;
|
||||||
|
for (auto cur : CURSOR_DATA)
|
||||||
|
{
|
||||||
|
if (hCursor == cur.Item1)
|
||||||
|
{
|
||||||
|
drawMouseArrow(cursorInfo.ptScreenPos.x, cursorInfo.ptScreenPos.y, mdown, cur.Item2);
|
||||||
|
hCursor = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hCursor) drawMouseArrow(cursorInfo.ptScreenPos.x, cursorInfo.ptScreenPos.y, mdown, CURSOR_DATA[0].Item2);
|
||||||
|
#pragma endregion
|
||||||
|
}
|
||||||
|
pLock->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
_encoder->AddVideoFrame(WIC);
|
||||||
|
desktopTexture2D->Release();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (cnv)
|
||||||
|
{
|
||||||
|
_encoder->AddVideoFrame(WIC);
|
||||||
|
}
|
||||||
|
currFrame++;
|
||||||
|
while ((_encoder->VideoTimeStamp - _encoder->AudioTimeStamp) >= 100'000)
|
||||||
|
{
|
||||||
|
_encoder->AddAudioFrame(_zero_buffer_Audio, 3840, 100'000);
|
||||||
|
}
|
||||||
|
//等待FPS间隔
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(now - startTime).count();
|
||||||
|
ULONGLONG frameTime = currFrame * (1000000 / FPS);
|
||||||
|
if (duration >= frameTime)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//结束全部流,关闭音频捕获
|
||||||
|
_encoder->EndAudio();
|
||||||
|
_encoder->End();
|
||||||
|
_audioCap->Stop();
|
||||||
|
delete _encoder;
|
||||||
|
delete _audioCap;
|
||||||
|
WIC->Release();
|
||||||
|
WIC = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void RenderGui(SIZE windowSize)
|
||||||
|
{
|
||||||
|
ImGui::Text(u8s("帧率:"));
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(windowSize.cx - (ImGui::GetCursorPos().x + 5));
|
||||||
|
ImGui::InputInt("##input_FPS", &FPS, 1, 100, _CaptureFrames ? ImGuiInputTextFlags_ReadOnly : 0);
|
||||||
|
|
||||||
|
ImGui::Text(u8s("码率:"));
|
||||||
|
ImGui::SameLine();
|
||||||
|
auto pos = ImGui::GetCursorPos();
|
||||||
|
ImGui::SetNextItemWidth(windowSize.cx - (ImGui::GetCursorPos().x + 5));
|
||||||
|
if (_CaptureFrames)
|
||||||
|
{
|
||||||
|
ImGui::Text(VIDEOBITRATE_Names[VIDEOBITRATE]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ImGui::BeginCombo("##GenerateAudio_GPT_weights_Sel", VIDEOBITRATE_Names[VIDEOBITRATE])) {
|
||||||
|
for (int n = 0; n < 7; n++) {
|
||||||
|
bool is_selected = (VIDEOBITRATE == n);
|
||||||
|
if (ImGui::Selectable(VIDEOBITRATE_Names[n], is_selected)) {
|
||||||
|
VIDEOBITRATE = n;
|
||||||
|
}
|
||||||
|
if (is_selected) {
|
||||||
|
ImGui::SetItemDefaultFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Checkbox(u8s("录制声音##CaptureSound"), &captureSound);
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if (!_CaptureFrames)
|
||||||
|
{
|
||||||
|
if (ImGui::Button(u8s("开始##CaptureStart"), ImVec2(windowSize.cx - (ImGui::GetCursorPos().x + 5), 0)))
|
||||||
|
{
|
||||||
|
_CaptureFrames = true;
|
||||||
|
auto cTime = DateTime::Now().ToString();
|
||||||
|
cTime = StringHelper::Replace(cTime, "-", "_");
|
||||||
|
cTime = StringHelper::Replace(cTime, " ", "_");
|
||||||
|
cTime = StringHelper::Replace(cTime, ".", "_");
|
||||||
|
cTime = StringHelper::Replace(cTime, ":", "_");
|
||||||
|
|
||||||
|
MP4_PATH = Convert::string_to_wstring(cTime + ".mp4");
|
||||||
|
auto dskPath = Environment::GetFolderPath(SpecialFolder::Desktop);
|
||||||
|
MP4_PATH = Convert::string_to_wstring(dskPath) + L"\\" + MP4_PATH;
|
||||||
|
|
||||||
|
CreateThread(
|
||||||
|
NULL, NULL, captureThread, NULL, NULL, NULL
|
||||||
|
//NULL, NULL, captureWin32Thread, NULL, NULL, NULL
|
||||||
|
);
|
||||||
|
StartTime = GetTickCount64() * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ImGui::Button(u8s("停止##CaptureEnd"), ImVec2(windowSize.cx - (ImGui::GetCursorPos().x + 5), 0)))
|
||||||
|
{
|
||||||
|
_CaptureFrames = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_CaptureFrames)
|
||||||
|
{
|
||||||
|
LONGLONG now = GetTickCount64();
|
||||||
|
if (now > StartTime)
|
||||||
|
{
|
||||||
|
static ID3D11Texture2D* texture = NULL;
|
||||||
|
static ID3D11ShaderResourceView* image = NULL;
|
||||||
|
if (WIC)
|
||||||
|
{
|
||||||
|
if (texture == NULL)
|
||||||
|
{
|
||||||
|
D3D11_TEXTURE2D_DESC texDesc = {};
|
||||||
|
ZeroMemory(&texDesc, sizeof(texDesc));
|
||||||
|
texDesc.Width = GetSystemMetrics(SM_CXSCREEN);
|
||||||
|
texDesc.Height = GetSystemMetrics(SM_CYSCREEN);
|
||||||
|
texDesc.MipLevels = 1;
|
||||||
|
texDesc.ArraySize = 1;
|
||||||
|
texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
texDesc.SampleDesc.Count = 1;
|
||||||
|
texDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
texDesc.MiscFlags = 0;
|
||||||
|
|
||||||
|
g_pd3dDevice->CreateTexture2D(&texDesc, nullptr, &texture);
|
||||||
|
|
||||||
|
// 创建着色器资源视图
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||||
|
srvDesc.Format = texDesc.Format;
|
||||||
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srvDesc.Texture2D.MipLevels = texDesc.MipLevels;
|
||||||
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||||
|
g_pd3dDevice->CreateShaderResourceView(texture, &srvDesc, &image);
|
||||||
|
}
|
||||||
|
if (texture && image)
|
||||||
|
{
|
||||||
|
BYTE* pData = NULL;
|
||||||
|
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mappedResource{};
|
||||||
|
HRESULT hr = g_pImmediateContext->Map(texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
WIC->CopyPixels(
|
||||||
|
NULL,
|
||||||
|
duplicator->Width * 4,
|
||||||
|
duplicator->Width * duplicator->Height * 4,
|
||||||
|
(BYTE*)mappedResource.pData);
|
||||||
|
g_pImmediateContext->Unmap(texture, 0);
|
||||||
|
}
|
||||||
|
if (image)
|
||||||
|
{
|
||||||
|
auto pos = ImGui::GetCursorPos();
|
||||||
|
float ww = windowSize.cx - (pos.x + 5);
|
||||||
|
float hh = ww * 0.5625;
|
||||||
|
ImGui::Image(image, ImVec2(ww, hh), ImVec2(0.0f, 1.0f), ImVec2(1.0f, 0.0f));
|
||||||
|
double SoundTime = (double(now) - double(StartTime)) / 1000.0;
|
||||||
|
int hours = SoundTime / 3600;
|
||||||
|
int remainingSeconds = fmod(SoundTime, 3600);
|
||||||
|
int minutes = remainingSeconds / 60;
|
||||||
|
int seconds = remainingSeconds % 60;
|
||||||
|
int mseconds = fmod(SoundTime, 1) * 1000;
|
||||||
|
auto tx = StringHelper::Format("%02d:%02d:%02d,%03d",
|
||||||
|
hours, minutes, seconds, mseconds
|
||||||
|
);
|
||||||
|
ImGui::Text(tx.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui::Text(u8s("未开始"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto pos = ImGui::GetCursorPos();
|
||||||
|
float ww = windowSize.cx - (pos.x + 5);
|
||||||
|
float hh = ww * 0.5625;
|
||||||
|
ImDrawRect(pos.x, pos.y, ww, hh, ImColor(1.0f, 1.0f, 1.0f, 1.0f), 2.5f);
|
||||||
|
ImGui::SetCursorPos(ImVec2(pos.x, pos.y + hh + 5));
|
||||||
|
ImGui::Text(u8s("未开始"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void Render()
|
||||||
|
{
|
||||||
|
g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, nullptr);
|
||||||
|
float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
|
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, black);
|
||||||
|
int width, height;
|
||||||
|
RECT rect;
|
||||||
|
GetClientRect(hwnd, &rect);
|
||||||
|
width = rect.right - rect.left;
|
||||||
|
height = rect.bottom - rect.top;
|
||||||
|
|
||||||
|
ImGui_ImplDX11_NewFrame();
|
||||||
|
ImGui_ImplWin32_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
ImGui::SetNextWindowSize(ImVec2((float)width, (float)height));
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||||
|
ImGui::Begin(u8s("##主窗口"), nullptr,
|
||||||
|
ImGuiWindowFlags_NoTitleBar |
|
||||||
|
ImGuiWindowFlags_NoResize |
|
||||||
|
ImGuiWindowFlags_NoMove |
|
||||||
|
ImGuiWindowFlags_NoScrollbar |
|
||||||
|
ImGuiWindowFlags_NoScrollWithMouse);
|
||||||
|
{
|
||||||
|
RenderGui({ width, height });
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
ImGui::EndFrame();
|
||||||
|
ImGui::Render();
|
||||||
|
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
g_pSwapChain->Present(0, 0);
|
||||||
|
}
|
||||||
|
void InitD3D(HWND hWnd) {
|
||||||
|
DXGI_SWAP_CHAIN_DESC sd;
|
||||||
|
ZeroMemory(&sd, sizeof(sd));
|
||||||
|
sd.BufferCount = 1;
|
||||||
|
sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
sd.OutputWindow = hWnd;
|
||||||
|
sd.SampleDesc.Count = 1;
|
||||||
|
sd.Windowed = TRUE;
|
||||||
|
|
||||||
|
D3D_FEATURE_LEVEL featureLevel;
|
||||||
|
const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 };
|
||||||
|
|
||||||
|
D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, featureLevels, 1,
|
||||||
|
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pImmediateContext);
|
||||||
|
}
|
||||||
|
void CreateRenderTarget() {
|
||||||
|
ID3D11Texture2D* pBackBuffer = nullptr;
|
||||||
|
g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||||
|
|
||||||
|
D3D11_RENDER_TARGET_VIEW_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||||
|
|
||||||
|
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &desc, &g_pRenderTargetView);
|
||||||
|
pBackBuffer->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||||
|
ImGui_ImplWin32_WndProcHandler(hWnd, message, wParam, lParam);
|
||||||
|
switch (message) {
|
||||||
|
case WM_DESTROY:
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
case WM_SIZE:
|
||||||
|
if (g_pSwapChain)
|
||||||
|
{
|
||||||
|
ImGui::GetIO().DisplaySize = ImVec2((float)LOWORD(lParam), (float)HIWORD(lParam));/*
|
||||||
|
if (g_pRenderTargetView) {
|
||||||
|
g_pRenderTargetView->Release();
|
||||||
|
g_pRenderTargetView = nullptr;
|
||||||
|
}*/
|
||||||
|
ID3D11Texture2D* pBackBuffer = nullptr;
|
||||||
|
HRESULT hr = g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_pRenderTargetView);
|
||||||
|
pBackBuffer->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_MOVE:
|
||||||
|
if (g_pSwapChain)
|
||||||
|
{
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void ConfigWindow()
|
||||||
|
{
|
||||||
|
TCHAR exePath[MAX_PATH]{};
|
||||||
|
GetModuleFileName(GetModuleHandle(NULL), exePath, MAX_PATH);
|
||||||
|
HICON hIcon = ExtractIcon(GetModuleHandle(NULL), exePath, 0);
|
||||||
|
WNDCLASSEX wc = {};
|
||||||
|
wc.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
wc.lpfnWndProc = WindowProc;
|
||||||
|
wc.hInstance = GetModuleHandleA(NULL);
|
||||||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOWFRAME);
|
||||||
|
wc.hIcon = hIcon;
|
||||||
|
wc.hIconSm = hIcon;
|
||||||
|
wc.lpszClassName = L"KNWindowClass";
|
||||||
|
RegisterClassEx(&wc);
|
||||||
|
int width = 300;
|
||||||
|
int height = 360;
|
||||||
|
hwnd = CreateWindow(
|
||||||
|
L"KNWindowClass",
|
||||||
|
L"码德录屏",
|
||||||
|
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
width, height,
|
||||||
|
NULL, NULL,
|
||||||
|
GetModuleHandle(NULL),
|
||||||
|
NULL);
|
||||||
|
SetClassLongPtr(hwnd, GCLP_HICON, (LONG_PTR)LoadIcon(NULL, IDI_APPLICATION));
|
||||||
|
}
|
||||||
|
void InitImGui() {
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
ImGui::CreateContext();
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
(void)io;
|
||||||
|
ImGui_ImplWin32_Init(hwnd);
|
||||||
|
ImGui_ImplDX11_Init(g_pd3dDevice, g_pImmediateContext);
|
||||||
|
ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
|
ImGui::GetIO().ImeWindowHandle = hwnd;
|
||||||
|
}
|
||||||
|
void CleanupImGui() {
|
||||||
|
ImGui_ImplDX11_Shutdown();
|
||||||
|
ImGui_ImplWin32_Shutdown();
|
||||||
|
ImGui::DestroyContext();
|
||||||
|
}
|
||||||
|
bool ConfigDXGIDuplicator()
|
||||||
|
{
|
||||||
|
HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &pD3DDevice_Duplicator, nullptr, &pContext_Duplicator);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return false;
|
||||||
|
//硬件加速桌面捕获对象
|
||||||
|
duplicator = new DXGIDuplicator();
|
||||||
|
if (!duplicator->InitD3D11Device(pD3DDevice_Duplicator, pContext_Duplicator))
|
||||||
|
return false;
|
||||||
|
if (!duplicator->InitDuplication())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void ConfigCursorData()
|
||||||
|
{
|
||||||
|
GENERATE_CURSOR_DATA(32512);
|
||||||
|
GENERATE_CURSOR_DATA(32513);
|
||||||
|
GENERATE_CURSOR_DATA(32514);
|
||||||
|
GENERATE_CURSOR_DATA(32515);
|
||||||
|
GENERATE_CURSOR_DATA(32516);
|
||||||
|
GENERATE_CURSOR_DATA(32642);
|
||||||
|
GENERATE_CURSOR_DATA(32643);
|
||||||
|
GENERATE_CURSOR_DATA(32644);
|
||||||
|
GENERATE_CURSOR_DATA(32645);
|
||||||
|
GENERATE_CURSOR_DATA(32646);
|
||||||
|
GENERATE_CURSOR_DATA(32648);
|
||||||
|
GENERATE_CURSOR_DATA(32649);
|
||||||
|
GENERATE_CURSOR_DATA(32650);
|
||||||
|
GENERATE_CURSOR_DATA(32651);
|
||||||
|
GENERATE_CURSOR_DATA(32671);
|
||||||
|
GENERATE_CURSOR_DATA(32672);
|
||||||
|
}
|
||||||
|
int main(int argc, const char** arg)
|
||||||
|
{
|
||||||
|
ConfigWindow();
|
||||||
|
ConfigCursorData();
|
||||||
|
InitD3D(hwnd);
|
||||||
|
CreateRenderTarget();
|
||||||
|
InitImGui();
|
||||||
|
ConfigDXGIDuplicator();
|
||||||
|
ShowWindow(hwnd, true);
|
||||||
|
MSG msg = {};
|
||||||
|
bool running = true;
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||||
|
{
|
||||||
|
if (msg.message == WM_QUIT)
|
||||||
|
break;
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
static LONGLONG lastRender = 0;
|
||||||
|
LONGLONG now = GetTickCount64();
|
||||||
|
if (now - lastRender > 10)
|
||||||
|
{
|
||||||
|
lastRender = now;
|
||||||
|
Render();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
g_pRenderTargetView->Release();
|
||||||
|
g_pSwapChain->Release();
|
||||||
|
g_pImmediateContext->Release();
|
||||||
|
g_pd3dDevice->Release();
|
||||||
|
return NULL;
|
||||||
|
}
|
BIN
ScreenRecoder/ScreenRecoder.rc
Normal file
BIN
ScreenRecoder/ScreenRecoder.rc
Normal file
Binary file not shown.
304
ScreenRecoder/ScreenRecoder.vcxproj
Normal file
304
ScreenRecoder/ScreenRecoder.vcxproj
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>17.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{f70f08d0-3a56-4e00-9941-a7b95d07ef2f}</ProjectGuid>
|
||||||
|
<RootNamespace>ScreenRecoder</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>MADERecoder</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ExternalIncludePath>D:\Projects\CppUtils;$(ExternalIncludePath)</ExternalIncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ExternalIncludePath>D:\Projects\CppUtils;$(ExternalIncludePath)</ExternalIncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ExternalIncludePath>D:\Projects\CppUtils;$(ExternalIncludePath)</ExternalIncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ExternalIncludePath>D:\Projects\CppUtils;$(ExternalIncludePath)</ExternalIncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<Profile>true</Profile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<Profile>true</Profile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<Profile>true</Profile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<Profile>true</Profile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Media\H264Encoder.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Clipboard.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Convert.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\CRandom.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\DataPack.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\DateTime.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Dialog.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Environment.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Event.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\File.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\FileInfo.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\FileStream.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Guid.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\HttpHelper.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\HttpHelper1.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\MD5.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Process.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\ProcessOperator.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Registry.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\SHA256.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Socket.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\SqliteHelper.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\StopWatch.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\StringBuilder.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\StringHelper.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Thread.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\TimeSpan.cpp" />
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Utils.cpp" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Graphics\Factory.cpp" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Graphics\Font.cpp" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Graphics\Graphics.cpp" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Graphics\nanosvg.cpp" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\sqlite\sqlite3.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\adler32.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\compress.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\crc32.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\deflate.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\infback.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\inffast.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\inflate.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\inftrees.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\trees.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\uncompr.c" />
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\zutil.c" />
|
||||||
|
<ClCompile Include="DXGIDuplicator.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_demo.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_draw.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_dx10.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_dx11.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_dx12.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_dx9.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_win32.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_tables.cpp" />
|
||||||
|
<ClCompile Include="ImGui\imgui_widgets.cpp" />
|
||||||
|
<ClCompile Include="ImHelper.cpp" />
|
||||||
|
<ClCompile Include="ScreenRecoder.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Media\AudioFile.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Media\H264Encoder.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Clipboard.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Convert.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\CRandom.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\DataPack.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\DateTime.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\defines.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Dialog.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Dictionary.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Environment.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Event.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\File.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\FileInfo.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\FileStream.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Guid.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\HttpHelper.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\httplib.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\json.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\List.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\MD5.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\MemLoadLibrary2.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Process.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\ProcessOperator.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Registry.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\SHA256.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Socket.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\SqliteHelper.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\StopWatch.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\StringBuilder.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\StringHelper.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Thread.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\TimeSpan.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Tuple.h" />
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Utils.h" />
|
||||||
|
<ClInclude Include="CursorData.h" />
|
||||||
|
<ClInclude Include="D3DX11.h" />
|
||||||
|
<ClInclude Include="D3DX11async.h" />
|
||||||
|
<ClInclude Include="D3DX11core.h" />
|
||||||
|
<ClInclude Include="D3DX11tex.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\Colors.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\Factory.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\Font.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\Graphics.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\nanosvg.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\sqlite\sqlite3.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\crc32.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\deflate.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\gzguts.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\inffast.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\inffixed.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\inflate.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\inftrees.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\trees.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\zconf.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\zlib.h" />
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\zutil.h" />
|
||||||
|
<ClInclude Include="DXGIDuplicator.h" />
|
||||||
|
<ClInclude Include="ImGui\imconfig.h" />
|
||||||
|
<ClInclude Include="ImGui\imgui.h" />
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_dx10.h" />
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_dx11.h" />
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_dx12.h" />
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_dx9.h" />
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_win32.h" />
|
||||||
|
<ClInclude Include="ImGui\imgui_internal.h" />
|
||||||
|
<ClInclude Include="ImGui\imstb_rectpack.h" />
|
||||||
|
<ClInclude Include="ImGui\imstb_textedit.h" />
|
||||||
|
<ClInclude Include="ImGui\imstb_truetype.h" />
|
||||||
|
<ClInclude Include="ImHelper.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="ScreenRecoder.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="Delogo.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Natvis Include="List.natvis" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
436
ScreenRecoder/ScreenRecoder.vcxproj.filters
Normal file
436
ScreenRecoder/ScreenRecoder.vcxproj.filters
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="源文件">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="资源文件">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Utils">
|
||||||
|
<UniqueIdentifier>{b7621aa0-4db6-4ac1-96eb-9089c6d17184}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Utils\sqlite">
|
||||||
|
<UniqueIdentifier>{63ae819e-bbcb-47f6-b32a-4cd53dec1207}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Utils\zlib">
|
||||||
|
<UniqueIdentifier>{9ded0eaa-af1c-423b-824b-b71827e0cdaa}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="ImGui">
|
||||||
|
<UniqueIdentifier>{ed3af08b-fc0c-4d4e-bc04-6c929bfc74e3}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Graphics">
|
||||||
|
<UniqueIdentifier>{04e5d885-4d31-4720-9fbb-b8be3e1990ee}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Media">
|
||||||
|
<UniqueIdentifier>{d8dc376d-8050-4ba3-aebc-fd07cb9430fb}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="ScreenRecoder.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\adler32.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\compress.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\crc32.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\deflate.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\infback.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\inffast.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\inflate.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\inftrees.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\trees.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\uncompr.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\zlib\zutil.c">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Utils\sqlite\sqlite3.c">
|
||||||
|
<Filter>Utils\sqlite</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DXGIDuplicator.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_demo.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_draw.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_dx10.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_dx11.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_dx12.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_dx9.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_impl_win32.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_tables.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImGui\imgui_widgets.cpp">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImHelper.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Graphics\Factory.cpp">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Graphics\Font.cpp">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Graphics\Graphics.cpp">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="D:\Projects\CppUtils\Graphics\nanosvg.cpp">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Media\H264Encoder.cpp">
|
||||||
|
<Filter>Media</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Clipboard.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Convert.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\CRandom.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\DataPack.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\DateTime.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Dialog.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Environment.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Event.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\File.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\FileInfo.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\FileStream.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Guid.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\HttpHelper.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\HttpHelper1.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\MD5.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Process.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\ProcessOperator.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Registry.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\SHA256.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Socket.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\SqliteHelper.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\StopWatch.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\StringBuilder.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\StringHelper.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Thread.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\TimeSpan.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\CppUtils\Utils\Utils.cpp">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\crc32.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\deflate.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\gzguts.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\inffast.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\inffixed.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\inflate.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\inftrees.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\trees.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\zconf.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\zlib.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\zlib\zutil.h">
|
||||||
|
<Filter>Utils\zlib</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Utils\sqlite\sqlite3.h">
|
||||||
|
<Filter>Utils\sqlite</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DXGIDuplicator.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imconfig.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imgui.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_dx10.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_dx11.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_dx12.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_dx9.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imgui_impl_win32.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imgui_internal.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imstb_rectpack.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imstb_textedit.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImGui\imstb_truetype.h">
|
||||||
|
<Filter>ImGui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="resource.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImHelper.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D3DX11.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D3DX11async.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D3DX11core.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D3DX11tex.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\Colors.h">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\Factory.h">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\Font.h">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\Graphics.h">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="D:\Projects\CppUtils\Graphics\nanosvg.h">
|
||||||
|
<Filter>Graphics</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="CursorData.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Media\AudioFile.h">
|
||||||
|
<Filter>Media</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Media\H264Encoder.h">
|
||||||
|
<Filter>Media</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Utils.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Clipboard.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Convert.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\CRandom.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\DataPack.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\DateTime.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\defines.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Dialog.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Dictionary.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Environment.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Event.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\File.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\FileInfo.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\FileStream.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Guid.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\HttpHelper.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\httplib.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\json.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\List.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\MD5.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\MemLoadLibrary2.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Process.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\ProcessOperator.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Registry.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\SHA256.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Socket.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\SqliteHelper.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\StopWatch.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\StringBuilder.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\StringHelper.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Thread.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\TimeSpan.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\CppUtils\Utils\Tuple.h">
|
||||||
|
<Filter>Utils</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="ScreenRecoder.rc">
|
||||||
|
<Filter>资源文件</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="Delogo.ico">
|
||||||
|
<Filter>资源文件</Filter>
|
||||||
|
</Image>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Natvis Include="List.natvis" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
BIN
ScreenRecoder/d3dx11.lib
Normal file
BIN
ScreenRecoder/d3dx11.lib
Normal file
Binary file not shown.
16
ScreenRecoder/resource.h
Normal file
16
ScreenRecoder/resource.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ 生成的包含文件。
|
||||||
|
// 供 ScreenRecoder.rc 使用
|
||||||
|
//
|
||||||
|
#define IDI_ICON1 101
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user