Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74c51e7072 | ||
|
|
267b286765 | ||
|
|
f060ffbfba | ||
|
|
467fa86f59 | ||
|
|
608509aa22 | ||
|
|
9aa488e100 | ||
|
|
4c225c21c9 | ||
|
|
b8b4238b5f | ||
|
|
4d2766ce3f | ||
|
|
f4096ec9fb | ||
|
|
0f43788650 | ||
|
|
1c1381a7ba | ||
|
|
08903cd27a | ||
|
|
d840983829 | ||
|
|
8a6cee9c2d | ||
|
|
f7798f752f | ||
|
|
70cfad90a9 | ||
|
|
c926127e49 | ||
|
|
03469ce429 | ||
|
|
f63e573f04 | ||
|
|
682553a5a2 | ||
|
|
b5fd483d6a | ||
|
|
0d2c0e02f0 | ||
|
|
6f876f65ed | ||
|
|
8434d803bb | ||
|
|
1c332ebca7 | ||
|
|
340e2d5194 | ||
|
|
e397f5eb84 | ||
|
|
c20c09e275 | ||
|
|
a0ca46630e | ||
|
|
5b5995d7d0 | ||
|
|
808a71ed6d | ||
|
|
da072aa9f3 | ||
|
|
7237d283ef | ||
|
|
4a28b5f341 | ||
|
|
10091be4b3 | ||
|
|
c41fe42aa3 | ||
|
|
c0e1967e2e | ||
|
|
f5a8a83c7e | ||
|
|
c251de3a30 | ||
|
|
b0877a49ed |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,6 +5,8 @@
|
||||
/[Bb]uild/
|
||||
/[Ww]iki/
|
||||
/[Mm]isc/
|
||||
/UnityPackageManager
|
||||
/Packages
|
||||
|
||||
# Autogenerated VS/MD solution and project files
|
||||
*.csproj
|
||||
@@ -28,3 +30,4 @@ sysinfo.txt
|
||||
/Assets/AssetStoreTools*
|
||||
/Assets/Extensions*
|
||||
/uDesktopDuplication.log
|
||||
.vs
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
420
Assets/uDesktopDuplication/Examples/Scenes/Buffer.unity
Normal file
420
Assets/uDesktopDuplication/Examples/Scenes/Buffer.unity
Normal file
@@ -0,0 +1,420 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!29 &1
|
||||
OcclusionCullingSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_OcclusionBakeSettings:
|
||||
smallestOccluder: 5
|
||||
smallestHole: 0.25
|
||||
backfaceThreshold: 100
|
||||
m_SceneGUID: 00000000000000000000000000000000
|
||||
m_OcclusionCullingData: {fileID: 0}
|
||||
--- !u!104 &2
|
||||
RenderSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 9
|
||||
m_Fog: 0
|
||||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||
m_FogMode: 3
|
||||
m_FogDensity: 0.01
|
||||
m_LinearFogStart: 0
|
||||
m_LinearFogEnd: 300
|
||||
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
||||
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
||||
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
||||
m_AmbientIntensity: 1
|
||||
m_AmbientMode: 0
|
||||
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_HaloStrength: 0.5
|
||||
m_FlareStrength: 1
|
||||
m_FlareFadeSpeed: 3
|
||||
m_HaloTexture: {fileID: 0}
|
||||
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_DefaultReflectionMode: 0
|
||||
m_DefaultReflectionResolution: 128
|
||||
m_ReflectionBounces: 1
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 11
|
||||
m_GIWorkflowMode: 0
|
||||
m_GISettings:
|
||||
serializedVersion: 2
|
||||
m_BounceScale: 1
|
||||
m_IndirectOutputScale: 1
|
||||
m_AlbedoBoost: 1
|
||||
m_TemporalCoherenceThreshold: 1
|
||||
m_EnvironmentLightingMode: 0
|
||||
m_EnableBakedLightmaps: 1
|
||||
m_EnableRealtimeLightmaps: 1
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 10
|
||||
m_Resolution: 2
|
||||
m_BakeResolution: 40
|
||||
m_AtlasSize: 1024
|
||||
m_AO: 0
|
||||
m_AOMaxDistance: 1
|
||||
m_CompAOExponent: 1
|
||||
m_CompAOExponentDirect: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
m_TextureCompression: 1
|
||||
m_FinalGather: 0
|
||||
m_FinalGatherFiltering: 1
|
||||
m_FinalGatherRayCount: 256
|
||||
m_ReflectionCompression: 2
|
||||
m_MixedBakeMode: 2
|
||||
m_BakeBackend: 1
|
||||
m_PVRSampling: 1
|
||||
m_PVRDirectSampleCount: 32
|
||||
m_PVRSampleCount: 500
|
||||
m_PVRBounces: 2
|
||||
m_PVRFilterTypeDirect: 0
|
||||
m_PVRFilterTypeIndirect: 0
|
||||
m_PVRFilterTypeAO: 0
|
||||
m_PVRFilteringMode: 1
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 5
|
||||
m_PVRFilteringGaussRadiusAO: 2
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_ShowResolutionOverlay: 1
|
||||
m_LightingDataAsset: {fileID: 0}
|
||||
m_UseShadowmask: 1
|
||||
--- !u!196 &4
|
||||
NavMeshSettings:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_BuildSettings:
|
||||
serializedVersion: 2
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1 &15787040
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 15787043}
|
||||
- component: {fileID: 15787042}
|
||||
- component: {fileID: 15787041}
|
||||
m_Layer: 0
|
||||
m_Name: Main Camera
|
||||
m_TagString: MainCamera
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!81 &15787041
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 15787040}
|
||||
m_Enabled: 1
|
||||
--- !u!20 &15787042
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 15787040}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 1
|
||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_FocalLength: 50
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 0
|
||||
orthographic size: 5
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 1
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!4 &15787043
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 15787040}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 1, z: -10}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &24328793 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 114000012274256594, guid: de6f36e446e5e8a48bf61fe198985bb4,
|
||||
type: 2}
|
||||
m_PrefabInternal: {fileID: 930860461}
|
||||
m_Script: {fileID: 11500000, guid: bb54a34570e4747429b1c5b66c69d356, type: 3}
|
||||
--- !u!1001 &86016649
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 10
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_RootOrder
|
||||
value: 3
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 114000012274256594, guid: de6f36e446e5e8a48bf61fe198985bb4,
|
||||
type: 2}
|
||||
propertyPath: invertX_
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 114000012274256594, guid: de6f36e446e5e8a48bf61fe198985bb4,
|
||||
type: 2}
|
||||
propertyPath: useClip_
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 23000011974915108, guid: de6f36e446e5e8a48bf61fe198985bb4,
|
||||
type: 2}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: c181d333a7bee7a44b94c0f4e02c4bd4, type: 2}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalScale.x
|
||||
value: 0.96
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalScale.y
|
||||
value: 0.54
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1000012642892690, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_Name
|
||||
value: Monitor Board Dst
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents:
|
||||
- {fileID: 114000012274256594, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
m_IsPrefabAsset: 0
|
||||
--- !u!1 &423308485
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 423308487}
|
||||
- component: {fileID: 423308486}
|
||||
m_Layer: 0
|
||||
m_Name: Directional Light
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!108 &423308486
|
||||
Light:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 423308485}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 8
|
||||
m_Type: 1
|
||||
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
|
||||
m_Intensity: 1
|
||||
m_Range: 10
|
||||
m_SpotAngle: 30
|
||||
m_CookieSize: 10
|
||||
m_Shadows:
|
||||
m_Type: 2
|
||||
m_Resolution: -1
|
||||
m_CustomResolution: -1
|
||||
m_Strength: 1
|
||||
m_Bias: 0.05
|
||||
m_NormalBias: 0.4
|
||||
m_NearPlane: 0.2
|
||||
m_Cookie: {fileID: 0}
|
||||
m_DrawHalo: 0
|
||||
m_Flare: {fileID: 0}
|
||||
m_RenderMode: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_Lightmapping: 4
|
||||
m_LightShadowCasterMode: 0
|
||||
m_AreaSize: {x: 1, y: 1}
|
||||
m_BounceIntensity: 1
|
||||
m_ColorTemperature: 6570
|
||||
m_UseColorTemperature: 0
|
||||
m_ShadowRadius: 0
|
||||
m_ShadowAngle: 0
|
||||
--- !u!4 &423308487
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 423308485}
|
||||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
||||
m_LocalPosition: {x: 0, y: 3, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!1001 &930860461
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 10
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_RootOrder
|
||||
value: 2
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 114000012274256594, guid: de6f36e446e5e8a48bf61fe198985bb4,
|
||||
type: 2}
|
||||
propertyPath: invertX_
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 114000012274256594, guid: de6f36e446e5e8a48bf61fe198985bb4,
|
||||
type: 2}
|
||||
propertyPath: useClip_
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 23000011974915108, guid: de6f36e446e5e8a48bf61fe198985bb4,
|
||||
type: 2}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: c181d333a7bee7a44b94c0f4e02c4bd4, type: 2}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalScale.x
|
||||
value: 0.96
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_LocalScale.y
|
||||
value: 0.54
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1000012642892690, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
propertyPath: m_Name
|
||||
value: Monitor Board Src
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
|
||||
m_IsPrefabAsset: 0
|
||||
--- !u!1 &1159532891 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 1000012642892690, guid: de6f36e446e5e8a48bf61fe198985bb4,
|
||||
type: 2}
|
||||
m_PrefabInternal: {fileID: 86016649}
|
||||
--- !u!114 &1159532892
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1159532891}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2bbc456c8248acd46976392616f32f8c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
uddTexture: {fileID: 24328793}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36c8d626679d64b46b75b9f1a2923647
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
72
Assets/uDesktopDuplication/Examples/Scripts/BufferExample.cs
Normal file
72
Assets/uDesktopDuplication/Examples/Scripts/BufferExample.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class BufferExample : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
uDesktopDuplication.Texture uddTexture;
|
||||
|
||||
Texture2D texture_;
|
||||
Color32[] pixels_;
|
||||
GCHandle handle_;
|
||||
IntPtr ptr_ = IntPtr.Zero;
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
|
||||
public static extern IntPtr memcpy(IntPtr dest, IntPtr src, int count);
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (!uddTexture) return;
|
||||
|
||||
uddTexture.monitor.useGetPixels = true;
|
||||
UpdateTexture();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (ptr_ != IntPtr.Zero) {
|
||||
handle_.Free();
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!uddTexture) return;
|
||||
|
||||
if (uddTexture.monitor.width != texture_.width ||
|
||||
uddTexture.monitor.height != texture_.height) {
|
||||
UpdateTexture();
|
||||
}
|
||||
|
||||
CopyTexture();
|
||||
}
|
||||
|
||||
void UpdateTexture()
|
||||
{
|
||||
var width = uddTexture.monitor.width;
|
||||
var height = uddTexture.monitor.height;
|
||||
|
||||
// TextureFormat.BGRA32 should be set but it causes an error now.
|
||||
texture_ = new Texture2D(width, height, TextureFormat.RGBA32, false);
|
||||
texture_.filterMode = FilterMode.Bilinear;
|
||||
pixels_ = texture_.GetPixels32();
|
||||
handle_ = GCHandle.Alloc(pixels_, GCHandleType.Pinned);
|
||||
ptr_ = handle_.AddrOfPinnedObject();
|
||||
|
||||
GetComponent<Renderer>().material.mainTexture = texture_;
|
||||
}
|
||||
|
||||
void CopyTexture()
|
||||
{
|
||||
var buffer = uddTexture.monitor.buffer;
|
||||
if (buffer == IntPtr.Zero) return;
|
||||
|
||||
var width = uddTexture.monitor.width;
|
||||
var height = uddTexture.monitor.height;
|
||||
memcpy(ptr_, buffer, width * height * sizeof(Byte) * 4);
|
||||
|
||||
texture_.SetPixels32(pixels_);
|
||||
texture_.Apply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bbc456c8248acd46976392616f32f8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -6,27 +6,38 @@ public class GetPixelsExample : MonoBehaviour
|
||||
|
||||
[SerializeField] int x = 100;
|
||||
[SerializeField] int y = 100;
|
||||
const int width = 64;
|
||||
const int height = 32;
|
||||
[SerializeField] int w = 64;
|
||||
[SerializeField] int h = 32;
|
||||
|
||||
public Texture2D texture;
|
||||
Color32[] colors = new Color32[width * height];
|
||||
Color32[] colors;
|
||||
|
||||
void CreateTextureIfNeeded()
|
||||
{
|
||||
if (!texture || texture.width != w || texture.height != h)
|
||||
{
|
||||
colors = new Color32[w * h];
|
||||
texture = new Texture2D(w, h, TextureFormat.ARGB32, false);
|
||||
GetComponent<Renderer>().material.mainTexture = texture;
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
||||
GetComponent<Renderer>().material.mainTexture = texture;
|
||||
CreateTextureIfNeeded();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
CreateTextureIfNeeded();
|
||||
|
||||
// must be called (performance will be slightly down).
|
||||
uDesktopDuplication.Manager.primary.useGetPixels = true;
|
||||
|
||||
var monitor = uddTexture.monitor;
|
||||
if (!monitor.hasBeenUpdated) return;
|
||||
|
||||
if (monitor.GetPixels(colors, x, y, width, height)) {
|
||||
if (monitor.GetPixels(colors, x, y, w, h)) {
|
||||
texture.SetPixels32(colors);
|
||||
texture.Apply();
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(MultipleMonitorCreator))]
|
||||
public class MultipleMonitorAnalyzer : MonoBehaviour
|
||||
{
|
||||
MultipleMonitorCreator creator_;
|
||||
Vector3 gazePoint_ = Vector3.zero;
|
||||
public Vector3 gazePoint
|
||||
{
|
||||
get { return gazePoint_; }
|
||||
private set
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(MultipleMonitorCreator))]
|
||||
public class MultipleMonitorAnalyzer : MonoBehaviour
|
||||
{
|
||||
MultipleMonitorCreator creator_;
|
||||
Vector3 gazePoint_ = Vector3.zero;
|
||||
public Vector3 gazePoint
|
||||
{
|
||||
get { return gazePoint_; }
|
||||
private set
|
||||
{
|
||||
gazePoint_ += (value - gazePoint) * (gazePointFilter / (1f / 60 / Time.deltaTime));
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Filters")]
|
||||
[Range(0f, 1f)] public float gazePointFilter = 0.1f;
|
||||
[Range(0f, 1f)] public float moveRectFilter = 0.05f;
|
||||
[Range(0f, 1f)] public float mouseFilter = 0.05f;
|
||||
[Range(0f, 1f)] public float dirtyRectFilter = 0.01f;
|
||||
[Range(0f, 1f)] public float noEventFilter = 0.01f;
|
||||
[Range(0f, 1f)] public float velocityFilter = 0.1f;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] bool drawGazePoint;
|
||||
[SerializeField] bool drawAveragePos;
|
||||
[SerializeField] bool drawMoveRects;
|
||||
[SerializeField] bool drawDirtyRects;
|
||||
|
||||
void Start()
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Filters")]
|
||||
[Range(0f, 1f)] public float gazePointFilter = 0.1f;
|
||||
[Range(0f, 1f)] public float moveRectFilter = 0.05f;
|
||||
[Range(0f, 1f)] public float mouseFilter = 0.05f;
|
||||
[Range(0f, 1f)] public float dirtyRectFilter = 0.01f;
|
||||
[Range(0f, 1f)] public float noEventFilter = 0.01f;
|
||||
[Range(0f, 1f)] public float velocityFilter = 0.1f;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] bool drawGazePoint;
|
||||
[SerializeField] bool drawAveragePos;
|
||||
[SerializeField] bool drawMoveRects;
|
||||
[SerializeField] bool drawDirtyRects;
|
||||
|
||||
void Start()
|
||||
{
|
||||
creator_ = GetComponent<MultipleMonitorCreator>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
var cursorMonitorId = uDesktopDuplication.Manager.cursorMonitorId;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
var cursorMonitorId = uDesktopDuplication.Manager.cursorMonitorId;
|
||||
for (int i = 0; i < creator_.monitors.Count; ++i) {
|
||||
var info = creator_.monitors[i];
|
||||
var analyzer =
|
||||
@@ -44,18 +44,18 @@ public class MultipleMonitorAnalyzer : MonoBehaviour
|
||||
UpdateAnalyzer(analyzer);
|
||||
if (info.uddTexture.monitorId == cursorMonitorId) {
|
||||
gazePoint = analyzer.averagePos;
|
||||
}
|
||||
}
|
||||
|
||||
if (drawGazePoint) DrawGazePoint();
|
||||
}
|
||||
|
||||
void DrawGazePoint()
|
||||
}
|
||||
}
|
||||
|
||||
if (drawGazePoint) DrawGazePoint();
|
||||
}
|
||||
|
||||
void DrawGazePoint()
|
||||
{
|
||||
Debug.DrawLine(transform.position, gazePoint, Color.magenta);
|
||||
}
|
||||
|
||||
void UpdateAnalyzer(GazePointAnalyzer analyzer)
|
||||
}
|
||||
|
||||
void UpdateAnalyzer(GazePointAnalyzer analyzer)
|
||||
{
|
||||
analyzer.moveRectFilter = moveRectFilter;
|
||||
analyzer.mouseFilter = mouseFilter;
|
||||
@@ -65,5 +65,5 @@ public class MultipleMonitorAnalyzer : MonoBehaviour
|
||||
analyzer.drawAveragePos = drawAveragePos;
|
||||
analyzer.drawMoveRects = drawMoveRects;
|
||||
analyzer.drawDirtyRects = drawDirtyRects;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class RaycastTest : MonoBehaviour
|
||||
public class RaycastExample : MonoBehaviour
|
||||
{
|
||||
public Transform from;
|
||||
public Transform to;
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,53 +1,150 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19d4c78204afead44b6de11427d7f2f6
|
||||
timeCreated: 1480693943
|
||||
guid: d3ab0ac3a3d6bb643af0a464a93be957
|
||||
timeCreated: 1503496900
|
||||
licenseType: Pro
|
||||
PluginImporter:
|
||||
serializedVersion: 1
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
Any:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
Editor:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
DefaultValueInitialized: true
|
||||
Linux:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86
|
||||
Linux64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
LinuxUniversal:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86
|
||||
OSXIntel:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXIntel64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
OSXUniversal:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
Win:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Win64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 0
|
||||
Exclude Editor: 0
|
||||
Exclude Linux: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude LinuxUniversal: 0
|
||||
Exclude OSXIntel: 0
|
||||
Exclude OSXIntel64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 0
|
||||
Exclude Win64: 1
|
||||
data:
|
||||
first:
|
||||
'': data
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
data:
|
||||
first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
data:
|
||||
first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
Exclude Editor: 0
|
||||
Exclude Linux: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude LinuxUniversal: 0
|
||||
Exclude OSXIntel: 0
|
||||
Exclude OSXIntel64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude WebGL: 0
|
||||
Exclude Win: 0
|
||||
Exclude Win64: 1
|
||||
data:
|
||||
first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
data:
|
||||
first:
|
||||
Facebook: WebGL
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
data:
|
||||
first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86
|
||||
data:
|
||||
first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXIntel
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXIntel64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
WebGL: WebGL
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
Binary file not shown.
@@ -1,54 +1,150 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02fc121822cf2ea4e82e16c4a28bf711
|
||||
timeCreated: 1477546714
|
||||
guid: 7cb91c9ae744dc5429005b20e11f4f37
|
||||
timeCreated: 1503505907
|
||||
licenseType: Pro
|
||||
PluginImporter:
|
||||
serializedVersion: 1
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
Any:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
Editor:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
Linux:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
Linux64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86_64
|
||||
LinuxUniversal:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
OSXIntel:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXIntel64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXUniversal:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
Win:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Win64:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 0
|
||||
Exclude Editor: 0
|
||||
Exclude Linux: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude LinuxUniversal: 0
|
||||
Exclude OSXIntel: 0
|
||||
Exclude OSXIntel64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 0
|
||||
data:
|
||||
first:
|
||||
'': data
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
data:
|
||||
first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
data:
|
||||
first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
Exclude Editor: 0
|
||||
Exclude Linux: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude LinuxUniversal: 0
|
||||
Exclude OSXIntel: 0
|
||||
Exclude OSXIntel64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude WebGL: 0
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 0
|
||||
data:
|
||||
first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
data:
|
||||
first:
|
||||
Facebook: WebGL
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
data:
|
||||
first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
data:
|
||||
first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXIntel
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXIntel64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
WebGL: WebGL
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -169,6 +169,8 @@ public static class Lib
|
||||
[DllImport("uDesktopDuplication", EntryPoint = "GetPixels")]
|
||||
private static extern bool GetPixels_Internal(int id, System.IntPtr ptr, int x, int y, int width, int height);
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern IntPtr GetBuffer(int id);
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern bool HasBeenUpdated(int id);
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern bool UseGetPixels(int id, bool use);
|
||||
|
||||
@@ -62,8 +62,13 @@ public class Manager : MonoBehaviour
|
||||
private float reinitializationTimer_ = 0f;
|
||||
private bool isFirstFrame_ = true;
|
||||
|
||||
public static event Lib.DebugLogDelegate onDebugLog = msg => Debug.Log(msg);
|
||||
public static event Lib.DebugLogDelegate onDebugErr = msg => Debug.LogError(msg);
|
||||
public static event Lib.DebugLogDelegate onDebugLog = OnDebugLog;
|
||||
public static event Lib.DebugLogDelegate onDebugErr = OnDebugErr;
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(Lib.DebugLogDelegate))]
|
||||
private static void OnDebugLog(string msg) { Debug.Log(msg); }
|
||||
[AOT.MonoPInvokeCallback(typeof(Lib.DebugLogDelegate))]
|
||||
private static void OnDebugErr(string msg) { Debug.LogError(msg); }
|
||||
|
||||
public delegate void ReinitializeHandler();
|
||||
public static event ReinitializeHandler onReinitialized;
|
||||
@@ -99,6 +104,12 @@ public class Manager : MonoBehaviour
|
||||
Lib.Initialize();
|
||||
|
||||
CreateMonitors();
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
Shader.DisableKeyword("USE_GAMMA_TO_LINEAR_SPACE");
|
||||
#else
|
||||
Shader.EnableKeyword("USE_GAMMA_TO_LINEAR_SPACE");
|
||||
#endif
|
||||
}
|
||||
|
||||
void OnApplicationQuit()
|
||||
|
||||
@@ -238,6 +238,11 @@ public class Monitor
|
||||
get { return Lib.GetDirtyRects(id); }
|
||||
}
|
||||
|
||||
public System.IntPtr buffer
|
||||
{
|
||||
get { return Lib.GetBuffer(id); }
|
||||
}
|
||||
|
||||
public bool hasBeenUpdated
|
||||
{
|
||||
get { return Lib.HasBeenUpdated(id); }
|
||||
|
||||
@@ -240,6 +240,13 @@ public class Texture : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
int clipPositionScaleKey_;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
clipPositionScaleKey_ = Shader.PropertyToID("_ClipPositionScale");
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (monitor == null) {
|
||||
@@ -271,7 +278,9 @@ public class Texture : MonoBehaviour
|
||||
|
||||
void RequireUpdate()
|
||||
{
|
||||
monitor.shouldBeUpdated = true;
|
||||
if (monitor != null) {
|
||||
monitor.shouldBeUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Reinitialize()
|
||||
@@ -283,8 +292,12 @@ public class Texture : MonoBehaviour
|
||||
void UpdateMaterial()
|
||||
{
|
||||
width = transform.localScale.x;
|
||||
rotation = monitor.rotation;
|
||||
material.SetVector("_ClipPositionScale", new Vector4(clipPos.x, clipPos.y, clipScale.x, clipScale.y));
|
||||
|
||||
if (monitor != null) {
|
||||
rotation = monitor.rotation;
|
||||
}
|
||||
|
||||
material.SetVector(clipPositionScaleKey_, new Vector4(clipPos.x, clipPos.y, clipScale.x, clipScale.y));
|
||||
}
|
||||
|
||||
public Vector3 GetWorldPositionFromCoord(Vector2 coord)
|
||||
@@ -401,6 +414,19 @@ public class Texture : MonoBehaviour
|
||||
// Calculate coordinates.
|
||||
var coordX = toAngle / halfWidthAngle * 0.5f;
|
||||
var coordY = ly / halfHeight * 0.5f;
|
||||
|
||||
// Zoom
|
||||
if (useClip) {
|
||||
coordX = clipPos.x + (0.5f + coordX) * clipScale.x;
|
||||
coordX -= Mathf.Floor(coordX);
|
||||
coordX -= 0.5f;
|
||||
|
||||
coordY = (1f - clipPos.y) + (coordY - 0.5f) * clipScale.y;
|
||||
coordY -= Mathf.Floor(coordY);
|
||||
coordY -= 0.5f;
|
||||
}
|
||||
|
||||
// Desktop position
|
||||
int desktopX = monitor.left + (int)((coordX + 0.5f) * monitor.width);
|
||||
int desktopY = monitor.top + (int)((0.5f - coordY) * monitor.height);
|
||||
|
||||
|
||||
@@ -58,9 +58,11 @@ inline float2 uddClipUV(float2 uv)
|
||||
|
||||
inline void uddConvertToLinearIfNeeded(inout fixed3 rgb)
|
||||
{
|
||||
#ifdef USE_GAMMA_TO_LINEAR_SPACE
|
||||
if (!IsGammaSpace()) {
|
||||
rgb = GammaToLinearSpace(rgb);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline fixed4 uddGetTexture(sampler2D tex, float2 uv)
|
||||
|
||||
@@ -31,6 +31,7 @@ SubShader
|
||||
#pragma multi_compile ___ USE_CLIP
|
||||
#pragma multi_compile ___ BEND_ON
|
||||
#pragma multi_compile _FORWARD_Y _FORWARD_Z
|
||||
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
|
||||
|
||||
#define SURFACE_SHADER
|
||||
#include "./uDD_Common.cginc"
|
||||
|
||||
@@ -55,6 +55,7 @@ Pass
|
||||
#pragma multi_compile ___ USE_CLIP
|
||||
#pragma multi_compile ___ BEND_ON
|
||||
#pragma multi_compile _FORWARD_Y _FORWARD_Z
|
||||
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
|
||||
ENDCG
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ Pass
|
||||
#pragma multi_compile ___ USE_CLIP
|
||||
#pragma multi_compile ___ BEND_ON
|
||||
#pragma multi_compile _FORWARD_Y _FORWARD_Z
|
||||
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
|
||||
ENDCG
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ DsOutput domain(
|
||||
float disp = length(_DispTex.SampleLevel(sampler_DispTex, o.f2TexCoord, 0)) * _DispFactor;
|
||||
f3Position.xyz += f3Normal * disp;
|
||||
|
||||
o.f4Position = mul(UNITY_MATRIX_MVP, float4(f3Position.xyz, 1.0));
|
||||
o.f4Position = UnityObjectToClipPos(float4(f3Position.xyz, 1.0));
|
||||
|
||||
return o;
|
||||
}
|
||||
@@ -168,6 +168,7 @@ Pass
|
||||
#pragma multi_compile ___ USE_CLIP
|
||||
#pragma multi_compile ___ BEND_ON
|
||||
#pragma multi_compile _FORWARD_Y _FORWARD_Z
|
||||
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
|
||||
ENDCG
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ Pass
|
||||
#pragma multi_compile ___ USE_CLIP
|
||||
#pragma multi_compile ___ BEND_ON
|
||||
#pragma multi_compile _FORWARD_Y _FORWARD_Z
|
||||
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
|
||||
ENDCG
|
||||
}
|
||||
|
||||
|
||||
5
Plugins/uDesktopDuplication/uDesktopDuplication.def
Normal file
5
Plugins/uDesktopDuplication/uDesktopDuplication.def
Normal file
@@ -0,0 +1,5 @@
|
||||
LIBRARY
|
||||
|
||||
EXPORTS
|
||||
UnityPluginLoad
|
||||
UnityPluginUnload
|
||||
34
Plugins/uDesktopDuplication/uDesktopDuplication.sln
Normal file
34
Plugins/uDesktopDuplication/uDesktopDuplication.sln
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uDesktopDuplication", "uDesktopDuplication\uDesktopDuplication.vcxproj", "{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Debug|x64.Build.0 = Debug|x64
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Debug|x86.Build.0 = Debug|Win32
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Release|Win32.Build.0 = Release|Win32
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Release|x64.ActiveCfg = Release|x64
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Release|x64.Build.0 = Release|x64
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -17,6 +17,29 @@ extern std::unique_ptr<MonitorManager> g_manager;
|
||||
extern std::queue<Message> g_messages;
|
||||
|
||||
|
||||
void OutputWindowsInformation()
|
||||
{
|
||||
const auto hModule = ::LoadLibrary(TEXT("ntdll.dll"));
|
||||
if (!hModule) return;
|
||||
|
||||
ScopedReleaser freeModule([&] { ::FreeLibrary(hModule); });
|
||||
|
||||
if (const auto address = ::GetProcAddress(hModule, "RtlGetVersion"))
|
||||
{
|
||||
using RtlGetVersionType = NTSTATUS(WINAPI *)(OSVERSIONINFOEXW*);
|
||||
const auto RtlGetVersion = reinterpret_cast<RtlGetVersionType>(address);
|
||||
|
||||
OSVERSIONINFOEXW os = { sizeof(os) };
|
||||
if (!FAILED(RtlGetVersion(&os)))
|
||||
{
|
||||
Debug::Log("OS Version : ", os.dwMajorVersion, ".", os.dwMinorVersion);
|
||||
Debug::Log("Build Number : ", os.dwBuildNumber);
|
||||
Debug::Log("Service Pack : ", os.szCSDVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IUnityInterfaces* GetUnity()
|
||||
{
|
||||
return g_unity;
|
||||
@@ -37,7 +60,9 @@ const std::unique_ptr<MonitorManager>& GetMonitorManager()
|
||||
|
||||
LUID GetUnityAdapterLuid()
|
||||
{
|
||||
const auto device = GetUnity()->Get<IUnityGraphicsD3D11>()->GetDevice();
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
const auto device = GetDevice();
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIDevice1> dxgiDevice;
|
||||
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)))){
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
|
||||
|
||||
// Output windows version
|
||||
void OutputWindowsInformation();
|
||||
|
||||
// Unity interface getter
|
||||
struct IUnityInterfaces;
|
||||
IUnityInterfaces* GetUnity();
|
||||
|
||||
@@ -21,6 +21,8 @@ Cursor::~Cursor()
|
||||
|
||||
void Cursor::UpdateBuffer(Duplicator* duplicator, const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (frameInfo.LastMouseUpdateTime.QuadPart == 0)
|
||||
{
|
||||
return;
|
||||
@@ -62,16 +64,18 @@ void Cursor::UpdateBuffer(Duplicator* duplicator, const DXGI_OUTDUPL_FRAME_INFO&
|
||||
}
|
||||
|
||||
|
||||
void Cursor::Draw(
|
||||
void Cursor::UpdateTexture(
|
||||
Duplicator* duplicator,
|
||||
const ComPtr<ID3D11Texture2D>& targetTexture)
|
||||
const ComPtr<ID3D11Texture2D>& desktopTexture)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
auto monitor = duplicator->GetMonitor();
|
||||
|
||||
// Check desktop texure
|
||||
if (targetTexture == nullptr)
|
||||
if (desktopTexture == nullptr)
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => target texture is null.");
|
||||
Debug::Error("Cursor::UpdateTexture() => Desktop texture is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -97,6 +101,7 @@ void Cursor::Draw(
|
||||
// Check buffers
|
||||
if (!bgraBuffer_ || !buffer_)
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => no buffer.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -193,7 +198,7 @@ void Cursor::Draw(
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_BOX capturedImageArea
|
||||
capturedImageArea_ = D3D11_BOX
|
||||
{
|
||||
static_cast<UINT>(capturedImageLeft),
|
||||
static_cast<UINT>(capturedImageTop),
|
||||
@@ -230,7 +235,7 @@ void Cursor::Draw(
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
duplicator->GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, targetTexture.Get(), 0, &capturedImageArea);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, desktopTexture.Get(), 0, &capturedImageArea_);
|
||||
}
|
||||
|
||||
// Get mapped surface to access pixels in CPU
|
||||
@@ -358,12 +363,6 @@ void Cursor::Draw(
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
duplicator->GetDevice()->GetImmediateContext(&context);
|
||||
context->UpdateSubresource(targetTexture.Get(), 0, &capturedImageArea, bgraBuffer_.Get(), capturedImageWidth * 4, 0);
|
||||
}
|
||||
|
||||
if (FAILED(surface->Unmap()))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => surface->Unmap() failed.");
|
||||
@@ -372,8 +371,27 @@ void Cursor::Draw(
|
||||
}
|
||||
|
||||
|
||||
void Cursor::Draw(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (texture == nullptr)
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => Desktop texture is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto capturedImageWidth = capturedImageArea_.right - capturedImageArea_.left;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->UpdateSubresource(texture.Get(), 0, &capturedImageArea_, bgraBuffer_.Get(), capturedImageWidth * 4, 0);
|
||||
}
|
||||
|
||||
|
||||
void Cursor::GetTexture(ID3D11Texture2D* texture)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (!bgraBuffer_)
|
||||
{
|
||||
Debug::Error("Cursor::GetTexture() => bgra32Buffer is null.");
|
||||
|
||||
@@ -17,9 +17,10 @@ public:
|
||||
void UpdateBuffer(
|
||||
Duplicator* duplicator,
|
||||
const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
|
||||
void Draw(
|
||||
Duplicator* duplicator,
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& targetTexture);
|
||||
void UpdateTexture(
|
||||
Duplicator* duplicator,
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& desktopTexture);
|
||||
void Draw(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture);
|
||||
void GetTexture(ID3D11Texture2D* texture);
|
||||
|
||||
bool IsVisible() const;
|
||||
@@ -38,4 +39,5 @@ private:
|
||||
Buffer<BYTE> bgraBuffer_;
|
||||
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo_;
|
||||
LARGE_INTEGER timestamp_;
|
||||
D3D11_BOX capturedImageArea_;
|
||||
};
|
||||
@@ -39,4 +39,18 @@ void Debug::Finalize()
|
||||
}
|
||||
Debug::SetLogFunc(nullptr);
|
||||
Debug::SetErrorFunc(nullptr);
|
||||
}
|
||||
|
||||
|
||||
decltype(DebugFunctionScopedTimer::currentId) DebugFunctionScopedTimer::currentId = 0;
|
||||
|
||||
|
||||
DebugFunctionScopedTimer::DebugFunctionScopedTimer(const char* name)
|
||||
: ScopedTimer([this](std::chrono::microseconds us) {
|
||||
Debug::Log("<< [", id_, "]", name_, " : ", us.count(), "[us]");
|
||||
})
|
||||
, name_(name)
|
||||
, id_(currentId++)
|
||||
{
|
||||
Debug::Log(">> [", id_, "]", name_);
|
||||
}
|
||||
@@ -1,10 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
|
||||
#include "Common.h"
|
||||
#include "IUnityInterface.h"
|
||||
|
||||
|
||||
// Debug flag
|
||||
#ifdef _DEBUG
|
||||
#define UDD_DEBUG_ON
|
||||
#endif
|
||||
|
||||
|
||||
// Logging
|
||||
class Debug
|
||||
{
|
||||
@@ -32,12 +42,24 @@ private:
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void Output(T&& arg)
|
||||
static void Output(const T& arg)
|
||||
{
|
||||
if (mode_ == Mode::None) return;
|
||||
if (ss_.good())
|
||||
{
|
||||
ss_ << std::forward<T>(arg);
|
||||
ss_ << arg;
|
||||
}
|
||||
}
|
||||
|
||||
static void Output(const WCHAR* arg)
|
||||
{
|
||||
if (mode_ == Mode::None) return;
|
||||
if (ss_.good())
|
||||
{
|
||||
char buf[256];
|
||||
size_t size;
|
||||
wcstombs_s(&size, buf, arg, 256);
|
||||
ss_ << buf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,10 +103,10 @@ private:
|
||||
}
|
||||
|
||||
template <class Arg, class... RestArgs>
|
||||
static void _Log(Level level, Arg&& arg, RestArgs&&... restArgs)
|
||||
static void _Log(Level level, const Arg& arg, const RestArgs&... restArgs)
|
||||
{
|
||||
Output(std::forward<Arg>(arg));
|
||||
_Log(level, std::forward<RestArgs>(restArgs)...);
|
||||
Output(arg);
|
||||
_Log(level, restArgs...);
|
||||
}
|
||||
|
||||
static void _Log(Level level)
|
||||
@@ -133,4 +155,30 @@ private:
|
||||
static DebugLogFuncPtr logFunc_;
|
||||
static DebugLogFuncPtr errFunc_;
|
||||
static std::mutex mutex_;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class DebugFunctionScopedTimer : public ScopedTimer
|
||||
{
|
||||
public:
|
||||
explicit DebugFunctionScopedTimer(const char* name);
|
||||
|
||||
private:
|
||||
static unsigned int currentId;
|
||||
const char* const name_;
|
||||
const unsigned int id_;
|
||||
};
|
||||
|
||||
|
||||
#ifdef UDD_DEBUG_ON
|
||||
#define UDD_FUNCTION_SCOPE_TIMER \
|
||||
DebugFunctionScopedTimer _timer_##__COUNTER__(__FUNCTION__);
|
||||
#define UDD_SCOPE_TIMER(Name) \
|
||||
ScopedTimer _timer_##__COUNTER__([](std::chrono::microseconds us) \
|
||||
{ \
|
||||
Debug::Log(#Name, " : ", us.count(), " [us]"); \
|
||||
});
|
||||
#else
|
||||
#define UDD_FUNCTION_SCOPE_TIMER
|
||||
#define UDD_SCOPE_TIMER(Name)
|
||||
#endif
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "IUnityGraphicsD3D11.h"
|
||||
#include "Device.h"
|
||||
#include "Debug.h"
|
||||
#include "Common.h"
|
||||
|
||||
#pragma comment(lib, "d3d11.lib")
|
||||
|
||||
@@ -14,8 +15,7 @@ using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
|
||||
IsolatedD3D11Device::IsolatedD3D11Device(UINT cachedTextureNum)
|
||||
: cachedTextures_(cachedTextureNum)
|
||||
IsolatedD3D11Device::IsolatedD3D11Device()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ IsolatedD3D11Device::~IsolatedD3D11Device()
|
||||
|
||||
HRESULT IsolatedD3D11Device::Create(const ComPtr<IDXGIAdapter>& adapter)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
const auto driverType = adapter ?
|
||||
D3D_DRIVER_TYPE_UNKNOWN :
|
||||
D3D_DRIVER_TYPE_HARDWARE;
|
||||
@@ -65,42 +67,35 @@ ComPtr<ID3D11Device> IsolatedD3D11Device::GetDevice()
|
||||
}
|
||||
|
||||
|
||||
ComPtr<ID3D11Texture2D> IsolatedD3D11Device::GetCompatibleSharedTexture(
|
||||
const ComPtr<ID3D11Texture2D>& src,
|
||||
UINT index)
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> IsolatedD3D11Device::GetCompatibleSharedTexture(
|
||||
const ComPtr<ID3D11Texture2D>& src)
|
||||
{
|
||||
if (index < 0 || index >= cachedTextures_.size())
|
||||
{
|
||||
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => ", index, " is out of cachedTextures range.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto& cachedTexture = cachedTextures_.at(index);
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
D3D11_TEXTURE2D_DESC srcDesc;
|
||||
src->GetDesc(&srcDesc);
|
||||
|
||||
// check if the format and size of the current texture are same as the source one
|
||||
if (cachedTexture)
|
||||
if (cachedSharedTexture_)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC targetDesc;
|
||||
cachedTexture->GetDesc(&targetDesc);
|
||||
cachedSharedTexture_->GetDesc(&targetDesc);
|
||||
if (targetDesc.Format == srcDesc.Format &&
|
||||
targetDesc.Width == srcDesc.Width &&
|
||||
targetDesc.Height == srcDesc.Height)
|
||||
{
|
||||
return cachedTexture;
|
||||
return cachedSharedTexture_;
|
||||
}
|
||||
}
|
||||
|
||||
// for sharing this texture with unity device
|
||||
srcDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &cachedTexture)))
|
||||
if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &cachedSharedTexture_)))
|
||||
{
|
||||
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => Creating shared texture failed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return cachedTexture;
|
||||
return cachedSharedTexture_;
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
@@ -9,16 +11,15 @@
|
||||
class IsolatedD3D11Device
|
||||
{
|
||||
public:
|
||||
explicit IsolatedD3D11Device(UINT cachedTextureNum);
|
||||
IsolatedD3D11Device();
|
||||
~IsolatedD3D11Device();
|
||||
|
||||
HRESULT Create(const Microsoft::WRL::ComPtr<IDXGIAdapter>& adapter);
|
||||
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> GetCompatibleSharedTexture(
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src,
|
||||
UINT index);
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src);
|
||||
|
||||
private:
|
||||
Microsoft::WRL::ComPtr<ID3D11Device> device_;
|
||||
std::vector<Microsoft::WRL::ComPtr<ID3D11Texture2D>> cachedTextures_;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> cachedSharedTexture_;
|
||||
};
|
||||
|
||||
@@ -33,8 +33,9 @@ Duplicator::~Duplicator()
|
||||
|
||||
void Duplicator::InitializeDevice()
|
||||
{
|
||||
const UINT cachedTextureNum = 2;
|
||||
device_ = std::make_shared<IsolatedD3D11Device>(cachedTextureNum);
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
device_ = std::make_shared<IsolatedD3D11Device>();
|
||||
|
||||
if (FAILED(device_->Create(monitor_->GetAdapter())))
|
||||
{
|
||||
@@ -46,8 +47,11 @@ void Duplicator::InitializeDevice()
|
||||
|
||||
void Duplicator::InitializeDuplication()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
ComPtr<IDXGIOutput1> output1;
|
||||
if (FAILED(monitor_->GetOutput().As(&output1))) {
|
||||
if (FAILED(monitor_->GetOutput().As(&output1)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -57,17 +61,7 @@ void Duplicator::InitializeDuplication()
|
||||
case S_OK:
|
||||
{
|
||||
state_ = State::Ready;
|
||||
const auto rot = static_cast<DXGI_MODE_ROTATION>(monitor_->GetRotation());
|
||||
Debug::Log("Duplicator::Initialize() => OK.");
|
||||
Debug::Log(" ID : ", monitor_->GetId());
|
||||
Debug::Log(" Size : (", monitor_->GetWidth(), ", ", monitor_->GetHeight(), ")");
|
||||
Debug::Log(" DPI : (", monitor_->GetDpiX(), ", ", monitor_->GetDpiY(), ")");
|
||||
Debug::Log(" Rot : ",
|
||||
rot == DXGI_MODE_ROTATION_IDENTITY ? "Landscape" :
|
||||
rot == DXGI_MODE_ROTATION_ROTATE90 ? "Portrait" :
|
||||
rot == DXGI_MODE_ROTATION_ROTATE180 ? "Landscape (flipped)" :
|
||||
rot == DXGI_MODE_ROTATION_ROTATE270 ? "Portrait (flipped)" :
|
||||
"Unspecified");
|
||||
break;
|
||||
}
|
||||
case E_INVALIDARG:
|
||||
@@ -117,6 +111,8 @@ void Duplicator::InitializeDuplication()
|
||||
|
||||
void Duplicator::CheckUnityAdapter()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
monitor_->GetAdapter()->GetDesc(&desc);
|
||||
|
||||
@@ -135,6 +131,8 @@ void Duplicator::CheckUnityAdapter()
|
||||
|
||||
void Duplicator::Start()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (state_ != State::Ready) return;
|
||||
|
||||
Stop();
|
||||
@@ -162,7 +160,12 @@ void Duplicator::Start()
|
||||
});
|
||||
|
||||
const auto timeout = static_cast<UINT>(frameMilliSeconds);
|
||||
if (!Duplicate(timeout)) break;
|
||||
Duplicate(timeout);
|
||||
|
||||
if (state_ != State::Running)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (state_ == State::Running)
|
||||
@@ -175,6 +178,8 @@ void Duplicator::Start()
|
||||
|
||||
void Duplicator::Stop()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
shouldRun_ = false;
|
||||
|
||||
if (thread_.joinable())
|
||||
@@ -229,9 +234,13 @@ const Duplicator::Frame& Duplicator::GetLastFrame() const
|
||||
}
|
||||
|
||||
|
||||
bool Duplicator::Duplicate(UINT timeout)
|
||||
void Duplicator::Duplicate(UINT timeout)
|
||||
{
|
||||
if (!dupl_ || !device_) return false;
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (!dupl_ || !device_) return;
|
||||
|
||||
Release();
|
||||
|
||||
ComPtr<IDXGIResource> resource;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
@@ -247,89 +256,104 @@ bool Duplicator::Duplicate(UINT timeout)
|
||||
// it is necessary to re-initialize monitors.
|
||||
Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST.");
|
||||
state_ = State::AccessLost;
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case DXGI_ERROR_WAIT_TIMEOUT:
|
||||
{
|
||||
// This often occurs when timeout value is small and it is not problem.
|
||||
// Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_WAIT_TIMEOUT.");
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case DXGI_ERROR_INVALID_CALL:
|
||||
{
|
||||
Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL.");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case E_INVALIDARG:
|
||||
{
|
||||
Debug::Error("Duplicator::Duplicate() => E_INVALIDARG.");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
state_ = State::Unknown;
|
||||
Debug::Error("Duplicator::Duplicate() => Unknown Error.");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ScopedReleaser releaser([this]
|
||||
{
|
||||
const auto hr = dupl_->ReleaseFrame();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
switch (hr)
|
||||
{
|
||||
case DXGI_ERROR_ACCESS_LOST:
|
||||
{
|
||||
Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST.");
|
||||
state_ = State::AccessLost;
|
||||
break;
|
||||
}
|
||||
case DXGI_ERROR_INVALID_CALL:
|
||||
{
|
||||
Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
state_ = State::Unknown;
|
||||
Debug::Error("Duplicator::Duplicate() => Unknown Error.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
isFrameAcquired_ = true;
|
||||
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
if (FAILED(resource.As(&texture)))
|
||||
{
|
||||
return false;
|
||||
Debug::Error("Duplicator::Duplicate() => IDXGIResource could not be converted to ID3D11Texture2D.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto sharedTexture = device_->GetCompatibleSharedTexture(texture, frame % 2);
|
||||
auto sharedTexture = device_->GetCompatibleSharedTexture(texture);
|
||||
if (!sharedTexture)
|
||||
{
|
||||
return false;
|
||||
Debug::Error("Duplicator::Duplicate() => Shared texture is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
device_->GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(sharedTexture.Get(), texture.Get());
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
device_->GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(sharedTexture.Get(), texture.Get());
|
||||
}
|
||||
|
||||
UpdateCursor(sharedTexture, frameInfo);
|
||||
UpdateMetadata(frameInfo.TotalMetadataBufferSize);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
lastFrame_.frame = frame++;
|
||||
lastFrame_.texture = sharedTexture;
|
||||
lastFrame_.info = frameInfo;
|
||||
lastFrame_.metaData = metaData_;
|
||||
lastFrame_ = Frame
|
||||
{
|
||||
lastFrameId_++,
|
||||
sharedTexture,
|
||||
frameInfo,
|
||||
metaData_
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Duplicator::Release()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (!isFrameAcquired_) return;
|
||||
|
||||
const auto hr = dupl_->ReleaseFrame();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
switch (hr)
|
||||
{
|
||||
case DXGI_ERROR_ACCESS_LOST:
|
||||
{
|
||||
Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST.");
|
||||
state_ = State::AccessLost;
|
||||
break;
|
||||
}
|
||||
case DXGI_ERROR_INVALID_CALL:
|
||||
{
|
||||
Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
state_ = State::Unknown;
|
||||
Debug::Error("Duplicator::Duplicate() => Unknown Error.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
isFrameAcquired_ = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -337,6 +361,8 @@ void Duplicator::UpdateCursor(
|
||||
const ComPtr<ID3D11Texture2D>& texture,
|
||||
const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
auto& manager = GetMonitorManager();
|
||||
|
||||
if (frameInfo.PointerPosition.Visible)
|
||||
@@ -348,13 +374,15 @@ void Duplicator::UpdateCursor(
|
||||
{
|
||||
auto cursor = manager->GetCursor();
|
||||
cursor->UpdateBuffer(this, frameInfo);
|
||||
cursor->Draw(this, texture);
|
||||
cursor->UpdateTexture(this, texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Duplicator::UpdateMetadata(UINT totalBufferSize)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
metaData_.buffer.ExpandIfNeeded(totalBufferSize);
|
||||
if (!metaData_.buffer.Empty())
|
||||
{
|
||||
@@ -366,6 +394,8 @@ void Duplicator::UpdateMetadata(UINT totalBufferSize)
|
||||
|
||||
void Duplicator::UpdateMoveRects()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
const auto hr = dupl_->GetFrameMoveRects(
|
||||
metaData_.buffer.Size(),
|
||||
metaData_.buffer.As<DXGI_OUTDUPL_MOVE_RECT>(),
|
||||
@@ -408,6 +438,8 @@ void Duplicator::UpdateMoveRects()
|
||||
|
||||
void Duplicator::UpdateDirtyRects()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
const auto hr = dupl_->GetFrameDirtyRects(
|
||||
metaData_.buffer.Size() - metaData_.moveRectSize,
|
||||
metaData_.buffer.As<RECT>(metaData_.moveRectSize /* offset */),
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
struct Frame
|
||||
{
|
||||
UINT frame = 0;
|
||||
UINT id;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
|
||||
DXGI_OUTDUPL_FRAME_INFO info;
|
||||
Metadata metaData;
|
||||
@@ -67,7 +67,8 @@ private:
|
||||
void InitializeDuplication();
|
||||
void CheckUnityAdapter();
|
||||
|
||||
bool Duplicate(UINT timeout);
|
||||
void Duplicate(UINT timeout);
|
||||
void Release();
|
||||
|
||||
void UpdateCursor(
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture,
|
||||
@@ -76,13 +77,14 @@ private:
|
||||
void UpdateMoveRects();
|
||||
void UpdateDirtyRects();
|
||||
|
||||
Monitor* monitor_ = nullptr;
|
||||
Monitor* const monitor_ = nullptr;
|
||||
std::atomic<State> state_ = State::Ready;
|
||||
|
||||
std::shared_ptr<class IsolatedD3D11Device> device_;
|
||||
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> dupl_;
|
||||
Frame lastFrame_;
|
||||
UINT frame = 0;
|
||||
UINT lastFrameId_ = 0;
|
||||
bool isFrameAcquired_ = false;
|
||||
|
||||
volatile bool shouldRun_ = false;
|
||||
std::thread thread_;
|
||||
|
||||
@@ -21,7 +21,6 @@ Monitor::Monitor(int id)
|
||||
|
||||
Monitor::~Monitor()
|
||||
{
|
||||
duplicator_->Stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +29,8 @@ void Monitor::Initialize(
|
||||
const ComPtr<IDXGIOutput> &output
|
||||
)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
adapter_ = adapter;
|
||||
output_ = output;
|
||||
|
||||
@@ -58,44 +59,74 @@ void Monitor::Initialize(
|
||||
// DPI is set as -1, so the application has to use the appropriate value.
|
||||
}
|
||||
|
||||
const auto rot = outputDesc_.Rotation;
|
||||
Debug::Log("Monitor::Initialized() =>");
|
||||
Debug::Log(" ID : ", id_);
|
||||
Debug::Log(" Size : (", width_, ", ", height_, ")");
|
||||
Debug::Log(" DPI : (", dpiX_, ", ", dpiY_, ")");
|
||||
Debug::Log(" Rot : ",
|
||||
rot == DXGI_MODE_ROTATION_IDENTITY ? "Landscape" :
|
||||
rot == DXGI_MODE_ROTATION_ROTATE90 ? "Portrait" :
|
||||
rot == DXGI_MODE_ROTATION_ROTATE180 ? "Landscape (flipped)" :
|
||||
rot == DXGI_MODE_ROTATION_ROTATE270 ? "Portrait (flipped)" :
|
||||
"Unspecified");
|
||||
|
||||
duplicator_ = std::make_shared<Duplicator>(this);
|
||||
}
|
||||
|
||||
|
||||
void Monitor::Finalize()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
StopCapture();
|
||||
}
|
||||
|
||||
|
||||
void Monitor::Render()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
const auto& frame = duplicator_->GetLastFrame();
|
||||
const auto& texture = frame.texture;
|
||||
|
||||
if (!texture) return;
|
||||
if (frame.id == lastFrameId_) return;
|
||||
lastFrameId_ = frame.id;
|
||||
|
||||
// Get texture
|
||||
if (unityTexture_)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC srcDesc, dstDesc;
|
||||
texture->GetDesc(&srcDesc);
|
||||
unityTexture_->GetDesc(&dstDesc);
|
||||
if (srcDesc.Width != dstDesc.Width ||
|
||||
srcDesc.Height != dstDesc.Height)
|
||||
{
|
||||
Debug::Error("Monitor::Render() => Texture sizes are defferent.");
|
||||
Debug::Error(" Source : (", srcDesc.Width, ", ", srcDesc.Height, ")");
|
||||
Debug::Error(" Dest : (", dstDesc.Width, ", ", dstDesc.Height, ")");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(unityTexture_, texture.Get());
|
||||
}
|
||||
}
|
||||
if (unityTexture_ == nullptr)
|
||||
{
|
||||
Debug::Error("Monitor::Render() => Target texture has not been set yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frame.texture)
|
||||
{
|
||||
Debug::Error("Monitor::Render() => frame doesn't have texture.");
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC srcDesc, dstDesc;
|
||||
frame.texture->GetDesc(&srcDesc);
|
||||
unityTexture_->GetDesc(&dstDesc);
|
||||
if (srcDesc.Width != dstDesc.Width ||
|
||||
srcDesc.Height != dstDesc.Height)
|
||||
{
|
||||
Debug::Error("Monitor::Render() => Texture sizes are defferent.");
|
||||
Debug::Error(" Source : (", srcDesc.Width, ", ", srcDesc.Height, ")");
|
||||
Debug::Error(" Dest : (", dstDesc.Width, ", ", dstDesc.Height, ")");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(unityTexture_, frame.texture.Get());
|
||||
|
||||
auto& manager = GetMonitorManager();
|
||||
if (id_ == manager->GetCursorMonitorId())
|
||||
{
|
||||
manager->GetCursor()->Draw(unityTexture_);
|
||||
}
|
||||
}
|
||||
|
||||
if (UseGetPixels())
|
||||
{
|
||||
@@ -108,6 +139,8 @@ void Monitor::Render()
|
||||
|
||||
void Monitor::StartCapture()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (duplicator_->GetState() == DuplicatorState::Ready)
|
||||
{
|
||||
duplicator_->Start();
|
||||
@@ -117,6 +150,8 @@ void Monitor::StartCapture()
|
||||
|
||||
void Monitor::StopCapture()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
duplicator_->Stop();
|
||||
}
|
||||
|
||||
@@ -277,6 +312,8 @@ bool Monitor::UseGetPixels() const
|
||||
|
||||
void Monitor::CopyTextureFromGpuToCpu(ID3D11Texture2D* texture)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
const auto monitorRot = static_cast<DXGI_MODE_ROTATION>(GetRotation());
|
||||
const auto monitorWidth = GetWidth();
|
||||
const auto monitorHeight = GetHeight();
|
||||
@@ -342,6 +379,8 @@ void Monitor::CopyTextureFromGpuToCpu(ID3D11Texture2D* texture)
|
||||
|
||||
bool Monitor::GetPixels(BYTE* output, int x, int y, int width, int height)
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (!UseGetPixels())
|
||||
{
|
||||
Debug::Error("Monitor::GetPixels() => UseGetPixels(true) must have been called when you want to use GetPixels().");
|
||||
@@ -372,24 +411,24 @@ bool Monitor::GetPixels(BYTE* output, int x, int y, int width, int height)
|
||||
{
|
||||
left = y;
|
||||
top = monitorWidth - x - width;
|
||||
right = y + width;
|
||||
bottom = monitorWidth - x;
|
||||
right = y + width - 1;
|
||||
bottom = monitorWidth - x - 1;
|
||||
break;
|
||||
}
|
||||
case DXGI_MODE_ROTATION_ROTATE180:
|
||||
{
|
||||
left = monitorWidth - x - width;
|
||||
top = monitorHeight - y - height;
|
||||
right = monitorWidth - x;
|
||||
bottom = monitorHeight - y;
|
||||
right = monitorWidth - x - 1;
|
||||
bottom = monitorHeight - y - 1;
|
||||
break;
|
||||
}
|
||||
case DXGI_MODE_ROTATION_ROTATE270:
|
||||
{
|
||||
left = monitorHeight - y - height;
|
||||
top = x;
|
||||
right = monitorHeight - y;
|
||||
bottom = x + width;
|
||||
right = monitorHeight - y - 1;
|
||||
bottom = x + width - 1;
|
||||
break;
|
||||
}
|
||||
case DXGI_MODE_ROTATION_IDENTITY:
|
||||
@@ -398,8 +437,8 @@ bool Monitor::GetPixels(BYTE* output, int x, int y, int width, int height)
|
||||
{
|
||||
left = x;
|
||||
top = y;
|
||||
right = x + width;
|
||||
bottom = y + height;
|
||||
right = x + width - 1;
|
||||
bottom = y + height - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -450,7 +489,6 @@ bool Monitor::GetPixels(BYTE* output, int x, int y, int width, int height)
|
||||
const auto outCol = col;
|
||||
const auto outIndex = 4 * (outRow * width + outCol);
|
||||
|
||||
|
||||
// BGRA -> RGBA
|
||||
output[outIndex + 0] = bufferForGetPixels_[inIndex + 2];
|
||||
output[outIndex + 1] = bufferForGetPixels_[inIndex + 1];
|
||||
@@ -461,3 +499,14 @@ bool Monitor::GetPixels(BYTE* output, int x, int y, int width, int height)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
BYTE* Monitor::GetBuffer() const
|
||||
{
|
||||
if (!bufferForGetPixels_)
|
||||
{
|
||||
Debug::Error("Monitor::GetBuffer() => CopyTextureFromGpuToCpu() has not been called yet.");
|
||||
return nullptr;
|
||||
}
|
||||
return bufferForGetPixels_.Get();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Common.h"
|
||||
|
||||
|
||||
class MonitorManager;
|
||||
enum class DuplicatorState;
|
||||
|
||||
|
||||
@@ -52,15 +53,15 @@ public:
|
||||
void UseGetPixels(bool use);
|
||||
bool UseGetPixels() const;
|
||||
bool GetPixels(BYTE* output, int x, int y, int width, int height);
|
||||
BYTE* GetBuffer() const;
|
||||
|
||||
private:
|
||||
void CopyTextureFromGpuToCpu(ID3D11Texture2D* texture);
|
||||
|
||||
int id_ = -1;
|
||||
|
||||
MonitorManager* manager_ = nullptr;
|
||||
const int id_;
|
||||
UINT dpiX_ = -1, dpiY_ = -1;
|
||||
int width_ = -1, height_ = -1;
|
||||
|
||||
bool hasBeenUpdated_ = false;
|
||||
bool useGetPixels_ = false;
|
||||
|
||||
@@ -70,6 +71,7 @@ private:
|
||||
MONITORINFOEX monitorInfo_;
|
||||
|
||||
std::shared_ptr<class Duplicator> duplicator_;
|
||||
UINT lastFrameId_ = -1;
|
||||
|
||||
ID3D11Texture2D* unityTexture_ = nullptr;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> textureForGetPixels_;
|
||||
|
||||
@@ -18,23 +18,20 @@ using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
|
||||
MonitorManager::MonitorManager(LUID unityAdapterLuid)
|
||||
: unityAdapterLuid_(unityAdapterLuid)
|
||||
MonitorManager::MonitorManager()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MonitorManager::~MonitorManager()
|
||||
{
|
||||
Finalize();
|
||||
}
|
||||
|
||||
|
||||
void MonitorManager::Initialize()
|
||||
{
|
||||
Finalize();
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
// Get factory
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
||||
{
|
||||
@@ -42,27 +39,40 @@ void MonitorManager::Initialize()
|
||||
return;
|
||||
}
|
||||
|
||||
// Check all display adapters
|
||||
int id = 0;
|
||||
std::vector<std::pair<ComPtr<IDXGIAdapter1>, ComPtr<IDXGIOutput>>> outputs;
|
||||
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
||||
{
|
||||
// Search the main monitor from all outputs
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
if (FAILED(adapter->GetDesc(&desc))) continue;
|
||||
Debug::Log("Graphics Card [", i, "] : ", desc.Description);
|
||||
|
||||
ComPtr<IDXGIOutput> output;
|
||||
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
||||
{
|
||||
auto monitor = std::make_shared<Monitor>(id++);
|
||||
const auto unityAdapterLuid = GetUnityAdapterLuid();
|
||||
monitor->Initialize(adapter, output);
|
||||
monitor->StartCapture();
|
||||
monitors_.push_back(monitor);
|
||||
DXGI_OUTPUT_DESC desc;
|
||||
if (FAILED(output->GetDesc(&desc))) continue;
|
||||
Debug::Log(" > Monitor[", j, "] : ", desc.DeviceName);
|
||||
outputs.emplace_back(adapter, output);
|
||||
}
|
||||
}
|
||||
|
||||
for (int id = 0; id < static_cast<int>(outputs.size()); ++id)
|
||||
{
|
||||
const auto& pair = outputs.at(id);
|
||||
auto monitor = std::make_shared<Monitor>(id);
|
||||
monitor->Initialize(pair.first, pair.second);
|
||||
monitor->StartCapture();
|
||||
monitors_.push_back(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MonitorManager::Finalize()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
for (const auto& monitor : monitors_)
|
||||
{
|
||||
monitor->Finalize();
|
||||
@@ -74,6 +84,8 @@ void MonitorManager::Finalize()
|
||||
|
||||
void MonitorManager::Update()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
if (isReinitializationRequired_)
|
||||
{
|
||||
Reinitialize();
|
||||
@@ -84,13 +96,17 @@ void MonitorManager::Update()
|
||||
|
||||
void MonitorManager::RequireReinitilization()
|
||||
{
|
||||
Debug::Log("MonitorManager::Reinitialize() was required.");
|
||||
isReinitializationRequired_ = true;
|
||||
}
|
||||
|
||||
|
||||
void MonitorManager::Reinitialize()
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
Debug::Log("MonitorManager::Reinitialize()");
|
||||
Finalize();
|
||||
Initialize();
|
||||
SendMessageToUnity(Message::Reinitialized);
|
||||
}
|
||||
@@ -98,6 +114,8 @@ void MonitorManager::Reinitialize()
|
||||
|
||||
bool MonitorManager::HasMonitorCountChanged() const
|
||||
{
|
||||
UDD_FUNCTION_SCOPE_TIMER
|
||||
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ class Cursor;
|
||||
class MonitorManager
|
||||
{
|
||||
public:
|
||||
explicit MonitorManager(LUID unityAdapterLuid_);
|
||||
MonitorManager();
|
||||
~MonitorManager();
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
@@ -34,7 +34,6 @@ public:
|
||||
int GetTotalHeight() const;
|
||||
|
||||
private:
|
||||
LUID unityAdapterLuid_;
|
||||
UINT frameRate_ = 60;
|
||||
bool enableTextureCopyFromGpuToCpu_ = false;
|
||||
std::vector<std::shared_ptr<Monitor>> monitors_;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
IUnityInterfaces* g_unity = nullptr;
|
||||
std::unique_ptr<MonitorManager> g_manager;
|
||||
std::queue<Message> g_messages;
|
||||
ID3D11DeviceContext* g_deviceContextForMainThread = nullptr;
|
||||
|
||||
|
||||
extern "C"
|
||||
@@ -35,38 +34,24 @@ extern "C"
|
||||
|
||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API Initialize()
|
||||
{
|
||||
if (g_unity && !g_manager)
|
||||
if (!g_unity) return;
|
||||
|
||||
if (!g_manager)
|
||||
{
|
||||
Debug::Initialize();
|
||||
|
||||
auto device = g_unity->Get<IUnityGraphicsD3D11>()->GetDevice();
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIDevice1> dxgiDevice;
|
||||
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)))){
|
||||
Debug::Error("fatal");
|
||||
return;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
|
||||
if (FAILED(dxgiDevice->GetAdapter(&dxgiAdapter))) {
|
||||
Debug::Error("fatal");
|
||||
return;
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
dxgiAdapter->GetDesc(&desc);
|
||||
|
||||
g_manager = std::make_unique<MonitorManager>(desc.AdapterLuid);
|
||||
OutputWindowsInformation();
|
||||
g_manager = std::make_unique<MonitorManager>();
|
||||
g_manager->Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API Finalize()
|
||||
{
|
||||
if (!g_manager) return;
|
||||
|
||||
g_manager->Finalize();
|
||||
g_manager.reset();
|
||||
if (g_manager)
|
||||
{
|
||||
g_manager->Finalize();
|
||||
g_manager.reset();
|
||||
}
|
||||
|
||||
std::queue<Message> empty;
|
||||
g_messages.swap(empty);
|
||||
@@ -381,7 +366,7 @@ extern "C"
|
||||
return 0;
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT void* UNITY_INTERFACE_API GetMoveRects(int id)
|
||||
UNITY_INTERFACE_EXPORT DXGI_OUTDUPL_MOVE_RECT* UNITY_INTERFACE_API GetMoveRects(int id)
|
||||
{
|
||||
if (!g_manager) return nullptr;
|
||||
if (auto monitor = g_manager->GetMonitor(id))
|
||||
@@ -401,7 +386,7 @@ extern "C"
|
||||
return 0;
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT void* UNITY_INTERFACE_API GetDirtyRects(int id)
|
||||
UNITY_INTERFACE_EXPORT RECT* UNITY_INTERFACE_API GetDirtyRects(int id)
|
||||
{
|
||||
if (!g_manager) return nullptr;
|
||||
if (auto monitor = g_manager->GetMonitor(id))
|
||||
@@ -413,7 +398,7 @@ extern "C"
|
||||
|
||||
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API GetPixels(int id, BYTE* output, int x, int y, int width, int height)
|
||||
{
|
||||
if (!g_manager) return nullptr;
|
||||
if (!g_manager) return false;
|
||||
if (auto monitor = g_manager->GetMonitor(id))
|
||||
{
|
||||
return monitor->GetPixels(output, x, y, width, height);
|
||||
@@ -421,6 +406,16 @@ extern "C"
|
||||
return false;
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT BYTE* UNITY_INTERFACE_API GetBuffer(int id)
|
||||
{
|
||||
if (!g_manager) return nullptr;
|
||||
if (auto monitor = g_manager->GetMonitor(id))
|
||||
{
|
||||
return monitor->GetBuffer();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API HasBeenUpdated(int id)
|
||||
{
|
||||
if (!g_manager) return nullptr;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -21,7 +21,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}</ProjectGuid>
|
||||
<RootNamespace>uDesktopDuplication</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>uDesktopDuplication</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
@@ -82,6 +82,8 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);include</IncludePath>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -92,6 +94,10 @@
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86_64"</Command>
|
||||
</PostBuildEvent>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -100,8 +106,11 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86_64"</Command>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86"</Command>
|
||||
</PostBuildEvent>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>$(SolutionDir)$(ProjectName).def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -115,6 +124,8 @@
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86_64"</Command>
|
||||
@@ -132,6 +143,7 @@
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>$(SolutionDir)$(ProjectName).def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86"</Command>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6
ProjectSettings/PresetManager.asset
Normal file
6
ProjectSettings/PresetManager.asset
Normal file
@@ -0,0 +1,6 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1386491679 &1
|
||||
PresetManager:
|
||||
m_ObjectHideFlags: 0
|
||||
m_DefaultList: []
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
m_EditorVersion: 5.5.0f3
|
||||
m_EditorVersion: 2018.2.15f1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,7 +2,6 @@ uDesktopDuplication
|
||||
===================
|
||||
|
||||

|
||||

|
||||
|
||||
**uDesktopDuplication** is an Unity asset to use the realtime screen capture as `Texture2D` using Desktop Duplication API.
|
||||
|
||||
@@ -28,7 +27,7 @@ Usage
|
||||
Attach `uDesktopDuplication/Texture` component to the target object, then its main texture will be replaced with the captured screen. Please see example scenes for more details.
|
||||
|
||||
|
||||
Lisence
|
||||
License
|
||||
-------
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user