Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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.
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.
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -271,7 +271,10 @@ public class Texture : MonoBehaviour
|
||||
|
||||
void RequireUpdate()
|
||||
{
|
||||
monitor.shouldBeUpdated = true;
|
||||
if (monitor != null)
|
||||
{
|
||||
monitor.shouldBeUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Reinitialize()
|
||||
@@ -280,11 +283,16 @@ public class Texture : MonoBehaviour
|
||||
monitor = Manager.GetMonitor(lastMonitorId_);
|
||||
}
|
||||
|
||||
int clipPositionScaleKey_ = Shader.PropertyToID("_ClipPositionScale");
|
||||
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 +409,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
|
||||
@@ -62,16 +62,16 @@ 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)
|
||||
{
|
||||
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 +97,7 @@ void Cursor::Draw(
|
||||
// Check buffers
|
||||
if (!bgraBuffer_ || !buffer_)
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => no buffer.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -193,7 +194,7 @@ void Cursor::Draw(
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_BOX capturedImageArea
|
||||
capturedImageArea_ = D3D11_BOX
|
||||
{
|
||||
static_cast<UINT>(capturedImageLeft),
|
||||
static_cast<UINT>(capturedImageTop),
|
||||
@@ -230,7 +231,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 +359,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,6 +367,21 @@ void Cursor::Draw(
|
||||
}
|
||||
|
||||
|
||||
void Cursor::Draw(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!bgraBuffer_)
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
@@ -1,10 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
|
||||
#include "Common.h"
|
||||
#include "IUnityInterface.h"
|
||||
|
||||
|
||||
// Debug flag
|
||||
#define UDD_DEBUG_ON
|
||||
|
||||
|
||||
// Logging
|
||||
class Debug
|
||||
{
|
||||
@@ -133,4 +141,21 @@ private:
|
||||
static DebugLogFuncPtr logFunc_;
|
||||
static DebugLogFuncPtr errFunc_;
|
||||
static std::mutex mutex_;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#ifdef UDD_DEBUG_ON
|
||||
#define UDD_FUNCTION_SCOPE_TIMER \
|
||||
ScopedTimer _timer_##__COUNTER__([](std::chrono::microseconds us) \
|
||||
{ \
|
||||
Debug::Log(__FUNCTION__, "@", __FILE__, ":", __LINE__, " => ", us.count(), " [us]"); \
|
||||
});
|
||||
#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()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,42 +65,33 @@ 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);
|
||||
|
||||
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,7 @@ Duplicator::~Duplicator()
|
||||
|
||||
void Duplicator::InitializeDevice()
|
||||
{
|
||||
const UINT cachedTextureNum = 2;
|
||||
device_ = std::make_shared<IsolatedD3D11Device>(cachedTextureNum);
|
||||
device_ = std::make_shared<IsolatedD3D11Device>();
|
||||
|
||||
if (FAILED(device_->Create(monitor_->GetAdapter())))
|
||||
{
|
||||
@@ -47,7 +46,8 @@ void Duplicator::InitializeDevice()
|
||||
void Duplicator::InitializeDuplication()
|
||||
{
|
||||
ComPtr<IDXGIOutput1> output1;
|
||||
if (FAILED(monitor_->GetOutput().As(&output1))) {
|
||||
if (FAILED(monitor_->GetOutput().As(&output1)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,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)
|
||||
@@ -229,9 +234,11 @@ const Duplicator::Frame& Duplicator::GetLastFrame() const
|
||||
}
|
||||
|
||||
|
||||
bool Duplicator::Duplicate(UINT timeout)
|
||||
void Duplicator::Duplicate(UINT timeout)
|
||||
{
|
||||
if (!dupl_ || !device_) return false;
|
||||
if (!dupl_ || !device_) return;
|
||||
|
||||
Release();
|
||||
|
||||
ComPtr<IDXGIResource> resource;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
@@ -247,89 +254,102 @@ 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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -348,7 +368,7 @@ void Duplicator::UpdateCursor(
|
||||
{
|
||||
auto cursor = manager->GetCursor();
|
||||
cursor->UpdateBuffer(this, frameInfo);
|
||||
cursor->Draw(this, texture);
|
||||
cursor->UpdateTexture(this, texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
@@ -82,7 +83,8 @@ private:
|
||||
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_;
|
||||
|
||||
@@ -71,31 +71,45 @@ void Monitor::Finalize()
|
||||
void Monitor::Render()
|
||||
{
|
||||
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())
|
||||
{
|
||||
@@ -450,7 +464,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];
|
||||
|
||||
@@ -70,6 +70,7 @@ private:
|
||||
MONITORINFOEX monitorInfo_;
|
||||
|
||||
std::shared_ptr<class Duplicator> duplicator_;
|
||||
UINT lastFrameId_ = -1;
|
||||
|
||||
ID3D11Texture2D* unityTexture_ = nullptr;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> textureForGetPixels_;
|
||||
|
||||
@@ -84,6 +84,7 @@ void MonitorManager::Update()
|
||||
|
||||
void MonitorManager::RequireReinitilization()
|
||||
{
|
||||
Debug::Log("MonitorManager::Reinitialize() was required.");
|
||||
isReinitializationRequired_ = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,14 +42,16 @@ extern "C"
|
||||
auto device = g_unity->Get<IUnityGraphicsD3D11>()->GetDevice();
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIDevice1> dxgiDevice;
|
||||
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)))){
|
||||
Debug::Error("fatal");
|
||||
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&dxgiDevice))))
|
||||
{
|
||||
Debug::Error("Initialize() => device->QueryInterface() failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
|
||||
if (FAILED(dxgiDevice->GetAdapter(&dxgiAdapter))) {
|
||||
Debug::Error("fatal");
|
||||
if (FAILED(dxgiDevice->GetAdapter(&dxgiAdapter)))
|
||||
{
|
||||
Debug::Error("Initialize() => dxgiDevice->GetAdapter() failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,33 +21,33 @@
|
||||
<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" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -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.7f1
|
||||
|
||||
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