diff --git a/Assets/uDesktopDuplication/Examples/Scenes/Zoom.unity b/Assets/uDesktopDuplication/Examples/Scenes/Zoom.unity new file mode 100644 index 0000000..22b39db Binary files /dev/null and b/Assets/uDesktopDuplication/Examples/Scenes/Zoom.unity differ diff --git a/Assets/uDesktopDuplication/Examples/Scenes/Zoom.unity.meta b/Assets/uDesktopDuplication/Examples/Scenes/Zoom.unity.meta new file mode 100644 index 0000000..47c4a16 --- /dev/null +++ b/Assets/uDesktopDuplication/Examples/Scenes/Zoom.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f3d41026babadc241b9d0852b0831584 +timeCreated: 1478436298 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uDesktopDuplication/Examples/Scripts/Loupe.cs b/Assets/uDesktopDuplication/Examples/Scripts/Loupe.cs new file mode 100644 index 0000000..b876a28 --- /dev/null +++ b/Assets/uDesktopDuplication/Examples/Scripts/Loupe.cs @@ -0,0 +1,37 @@ +using UnityEngine; + +public class Loupe : MonoBehaviour +{ + private uDesktopDuplication.Texture uddTexture_; + public float zoom = 3f; + public float aspect = 1f; + + void Start() + { + uddTexture_ = GetComponent(); + uddTexture_.useClip = true; + } + + void Update() + { + // To get other monitor textures, set dirty flag. + foreach (var monitor in uDesktopDuplication.Manager.monitors) { + monitor.CreateTexture(); + monitor.shouldBeUpdated = true; + } + + if (!uddTexture_.monitor.isCursorVisible) { + uddTexture_.monitorId = uDesktopDuplication.Manager.cursorMonitorId; + } + + var x = (float)uddTexture_.monitor.cursorX / uddTexture_.monitor.width; + var y = (float)uddTexture_.monitor.cursorY / uddTexture_.monitor.height; + var w = 1f / zoom; + var h = w / aspect * uddTexture_.monitor.aspect; + x = Mathf.Clamp(x - w / 2, 0f, 1f - w); + y = Mathf.Clamp(y - h / 2, 0f, 1f - h); + uddTexture_.clipPos = new Vector2(x, y); + uddTexture_.clipScale = new Vector2(w, h); + } +} + diff --git a/Assets/uDesktopDuplication/Examples/Scripts/Loupe.cs.meta b/Assets/uDesktopDuplication/Examples/Scripts/Loupe.cs.meta new file mode 100644 index 0000000..3519a13 --- /dev/null +++ b/Assets/uDesktopDuplication/Examples/Scripts/Loupe.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: efd9499cdb931b945947a2cd47909676 +timeCreated: 1478438457 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uDesktopDuplication/Plugins/uDesktopDuplication.dll b/Assets/uDesktopDuplication/Plugins/uDesktopDuplication.dll index a0c4896..6639cde 100644 Binary files a/Assets/uDesktopDuplication/Plugins/uDesktopDuplication.dll and b/Assets/uDesktopDuplication/Plugins/uDesktopDuplication.dll differ diff --git a/Assets/uDesktopDuplication/Scripts/Cursor.cs b/Assets/uDesktopDuplication/Scripts/Cursor.cs index b362203..cad4640 100644 --- a/Assets/uDesktopDuplication/Scripts/Cursor.cs +++ b/Assets/uDesktopDuplication/Scripts/Cursor.cs @@ -60,9 +60,8 @@ public class Cursor : MonoBehaviour void UpdateMaterial() { - bool isVisible = monitor.isCursorVisible; - var x = isVisible ? (float)monitor.cursorX / monitor.width : -9999f; - var y = isVisible ? (float)monitor.cursorY / monitor.height : -9999f; + var x = monitor.isCursorVisible ? (float)monitor.cursorX / monitor.width : -9999f; + var y = monitor.isCursorVisible ? (float)monitor.cursorY / monitor.height : -9999f; var w = (float)monitor.cursorShapeWidth / monitor.width; var h = (float)monitor.cursorShapeHeight / monitor.height; uddTexture_.material.SetVector("_CursorPositionScale", new Vector4(x, y, w, h)); diff --git a/Assets/uDesktopDuplication/Scripts/Lib.cs b/Assets/uDesktopDuplication/Scripts/Lib.cs index 30b4d8b..69eed92 100644 --- a/Assets/uDesktopDuplication/Scripts/Lib.cs +++ b/Assets/uDesktopDuplication/Scripts/Lib.cs @@ -56,6 +56,8 @@ public static class Lib [DllImport("uDesktopDuplication")] public static extern int GetMonitorCount(); [DllImport("uDesktopDuplication")] + public static extern int GetCursorMonitorId(); + [DllImport("uDesktopDuplication")] public static extern int GetTotalWidth(); [DllImport("uDesktopDuplication")] public static extern int GetTotalHeight(); diff --git a/Assets/uDesktopDuplication/Scripts/Manager.cs b/Assets/uDesktopDuplication/Scripts/Manager.cs index 099cffb..08ba353 100644 --- a/Assets/uDesktopDuplication/Scripts/Manager.cs +++ b/Assets/uDesktopDuplication/Scripts/Manager.cs @@ -38,6 +38,11 @@ public class Manager : MonoBehaviour get { return Lib.GetMonitorCount(); } } + static public int cursorMonitorId + { + get { return Lib.GetCursorMonitorId(); } + } + static public Monitor primary { get diff --git a/Assets/uDesktopDuplication/Scripts/Monitor.cs b/Assets/uDesktopDuplication/Scripts/Monitor.cs index 8152ca1..75e0995 100644 --- a/Assets/uDesktopDuplication/Scripts/Monitor.cs +++ b/Assets/uDesktopDuplication/Scripts/Monitor.cs @@ -196,7 +196,7 @@ public class Monitor Lib.GetCursorTexture(id, ptr); } - void CreateTexture() + public void CreateTexture() { if (!available) return; diff --git a/Assets/uDesktopDuplication/Scripts/Texture.cs b/Assets/uDesktopDuplication/Scripts/Texture.cs index 168b4bd..19ba926 100644 --- a/Assets/uDesktopDuplication/Scripts/Texture.cs +++ b/Assets/uDesktopDuplication/Scripts/Texture.cs @@ -24,9 +24,15 @@ public class Texture : MonoBehaviour set { monitor = Manager.monitors[Mathf.Clamp(value, 0, Manager.monitorCount - 1)]; } } + [Header("Invert UVs")] public bool invertX = false; public bool invertY = false; + [Header("Clip")] + public bool useClip = false; + public Vector2 clipPos = Vector2.zero; + public Vector2 clipScale = new Vector2(0.2f, 0.2f); + public Material material { get; @@ -55,6 +61,13 @@ public class Texture : MonoBehaviour } void UpdateMaterial() + { + Invert(); + Rotate(); + Clip(); + } + + void Invert() { if (invertX) { material.EnableKeyword("INVERT_X"); @@ -67,7 +80,10 @@ public class Texture : MonoBehaviour } else { material.DisableKeyword("INVERT_Y"); } + } + void Rotate() + { switch (monitor.rotation) { case MonitorRotation.Identity: @@ -94,6 +110,16 @@ public class Texture : MonoBehaviour break; } } + + void Clip() + { + if (useClip) { + material.EnableKeyword("USE_CLIP"); + material.SetVector("_ClipPositionScale", new Vector4(clipPos.x, clipPos.y, clipScale.x, clipScale.y)); + } else { + material.DisableKeyword("USE_CLIP"); + } + } } } \ No newline at end of file diff --git a/Assets/uDesktopDuplication/Shaders/uDD_Common.cginc b/Assets/uDesktopDuplication/Shaders/uDD_Common.cginc index 71b8b17..86bde2a 100644 --- a/Assets/uDesktopDuplication/Shaders/uDD_Common.cginc +++ b/Assets/uDesktopDuplication/Shaders/uDD_Common.cginc @@ -2,6 +2,7 @@ #define UDD_COMMON_CGINC #include "UnityCG.cginc" +#include "./uDD_Params.cginc" struct appdata { @@ -48,6 +49,13 @@ float2 uddRotateUV(float2 uv) return uv; } +float2 uddClipUV(float2 uv) +{ + uv.x = _ClipX + uv.x * _ClipWidth; + uv.y = _ClipY + uv.y * _ClipHeight; + return uv; +} + inline void uddConvertToLinearIfNeeded(inout fixed3 rgb) { if (!IsGammaSpace()) { @@ -55,27 +63,30 @@ inline void uddConvertToLinearIfNeeded(inout fixed3 rgb) } } -inline fixed4 uddGetScreenTexture(sampler2D tex, float2 uv) +inline fixed4 uddGetScreenTexture(float2 uv) { - fixed4 c = tex2D(tex, uv); + fixed4 c = tex2D(_MainTex, uv); return c; } -inline fixed4 uddGetCursorTexture(sampler2D tex, float2 uv, fixed4 cursorPosScale) +inline fixed4 uddGetCursorTexture(float2 uv) { - uv.x = (uv.x - cursorPosScale.x) / cursorPosScale.z; - uv.y = (uv.y - cursorPosScale.y) / cursorPosScale.w; - fixed4 c = tex2D(tex, uv); + uv.x = (uv.x - _CursorX) / _CursorWidth; + uv.y = (uv.y - _CursorY) / _CursorHeight; + fixed4 c = tex2D(_CursorTex, uv); fixed a = c.a * step(0, uv.x) * step(0, uv.y) * step(uv.x, 1) * step(uv.y, 1); c *= step(0.01, a); return c; } -inline fixed4 uddGetScreenTextureWithCursor(sampler2D screenTex, sampler2D cursorTex, float2 uv, fixed4 cursorPosScale) +inline fixed4 uddGetScreenTextureWithCursor(float2 uv) { uv = uddInvertUV(uv); - fixed4 screen = uddGetScreenTexture(screenTex, uddRotateUV(uv)); - fixed4 cursor = uddGetCursorTexture(cursorTex, uv, cursorPosScale); +#ifdef USE_CLIP + uv = uddClipUV(uv); +#endif + fixed4 screen = uddGetScreenTexture(uddRotateUV(uv)); + fixed4 cursor = uddGetCursorTexture(uv); fixed4 color = lerp(screen, cursor, cursor.a); uddConvertToLinearIfNeeded(color.rgb); return color; diff --git a/Assets/uDesktopDuplication/Shaders/uDD_Params.cginc b/Assets/uDesktopDuplication/Shaders/uDD_Params.cginc index 8da5e26..c119195 100644 --- a/Assets/uDesktopDuplication/Shaders/uDD_Params.cginc +++ b/Assets/uDesktopDuplication/Shaders/uDD_Params.cginc @@ -4,7 +4,18 @@ sampler2D _MainTex; fixed4 _Color; sampler2D _CursorTex; + half4 _CursorPositionScale; +#define _CursorX _CursorPositionScale.x +#define _CursorY _CursorPositionScale.y +#define _CursorWidth _CursorPositionScale.z +#define _CursorHeight _CursorPositionScale.w + +half4 _ClipPositionScale; +#define _ClipX _ClipPositionScale.x +#define _ClipY _ClipPositionScale.y +#define _ClipWidth _ClipPositionScale.z +#define _ClipHeight _ClipPositionScale.w #ifndef SURFACE_SHADER float4 _MainTex_ST; diff --git a/Assets/uDesktopDuplication/Shaders/uDD_Standard.shader b/Assets/uDesktopDuplication/Shaders/uDD_Standard.shader index 7621874..0b34bb5 100644 --- a/Assets/uDesktopDuplication/Shaders/uDD_Standard.shader +++ b/Assets/uDesktopDuplication/Shaders/uDD_Standard.shader @@ -22,19 +22,19 @@ SubShader #pragma surface surf Standard fullforwardshadows #pragma multi_compile ___ INVERT_X #pragma multi_compile ___ INVERT_Y - #pragma multi_compile ___ VERTICAL #pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270 + #pragma multi_compile ___ USE_BEND + #pragma multi_compile ___ USE_CLIP #define SURFACE_SHADER #include "./uDD_Common.cginc" - #include "./uDD_Params.cginc" half _Glossiness; half _Metallic; void surf(Input IN, inout SurfaceOutputStandard o) { - fixed4 c = uddGetScreenTextureWithCursor(_MainTex, _CursorTex, IN.uv_MainTex, _CursorPositionScale) * _Color; + fixed4 c = uddGetScreenTextureWithCursor(IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Metallic = _Metallic; o.Smoothness = _Glossiness; diff --git a/Assets/uDesktopDuplication/Shaders/uDD_Unlit.shader b/Assets/uDesktopDuplication/Shaders/uDD_Unlit.shader index 88910b1..3b10a5b 100644 --- a/Assets/uDesktopDuplication/Shaders/uDD_Unlit.shader +++ b/Assets/uDesktopDuplication/Shaders/uDD_Unlit.shader @@ -20,7 +20,6 @@ Cull [_Cull] CGINCLUDE #include "./uDD_Common.cginc" -#include "./uDD_Params.cginc" fixed _Radius; @@ -39,7 +38,7 @@ v2f vert(appdata v) fixed4 frag(v2f i) : SV_Target { - return uddGetScreenTextureWithCursor(_MainTex, _CursorTex, i.uv, _CursorPositionScale); + return uddGetScreenTextureWithCursor(i.uv); } ENDCG @@ -51,9 +50,9 @@ Pass #pragma fragment frag #pragma multi_compile ___ INVERT_X #pragma multi_compile ___ INVERT_Y - #pragma multi_compile ___ VERTICAL - #pragma shader_feature ___ USE_BEND #pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270 + #pragma multi_compile ___ USE_BEND + #pragma multi_compile ___ USE_CLIP ENDCG } diff --git a/Assets/uDesktopDuplication/Shaders/uDD_Unlit_BlackMask.shader b/Assets/uDesktopDuplication/Shaders/uDD_Unlit_BlackMask.shader index 21de4a4..cba3268 100644 --- a/Assets/uDesktopDuplication/Shaders/uDD_Unlit_BlackMask.shader +++ b/Assets/uDesktopDuplication/Shaders/uDD_Unlit_BlackMask.shader @@ -21,7 +21,6 @@ Blend SrcAlpha OneMinusSrcAlpha CGINCLUDE #include "./uDD_Common.cginc" -#include "./uDD_Params.cginc" fixed _Mask; @@ -35,7 +34,7 @@ v2f vert(appdata v) fixed4 frag(v2f i) : SV_Target { - fixed4 tex = uddGetScreenTextureWithCursor(_MainTex, _CursorTex, i.uv, _CursorPositionScale); + fixed4 tex = uddGetScreenTextureWithCursor(i.uv); fixed alpha = pow((tex.r + tex.g + tex.b) / 3.0, _Mask); return fixed4(tex.rgb * _Color.rgb, alpha * _Color.a); } @@ -49,8 +48,9 @@ Pass #pragma fragment frag #pragma multi_compile ___ INVERT_X #pragma multi_compile ___ INVERT_Y - #pragma multi_compile ___ VERTICAL #pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270 + #pragma multi_compile ___ USE_BEND + #pragma multi_compile ___ USE_CLIP ENDCG } diff --git a/Assets/uDesktopDuplication/Shaders/uDD_Unlit_Transparent.shader b/Assets/uDesktopDuplication/Shaders/uDD_Unlit_Transparent.shader index 8f795fc..cacea32 100644 --- a/Assets/uDesktopDuplication/Shaders/uDD_Unlit_Transparent.shader +++ b/Assets/uDesktopDuplication/Shaders/uDD_Unlit_Transparent.shader @@ -20,7 +20,6 @@ Blend SrcAlpha OneMinusSrcAlpha CGINCLUDE #include "./uDD_Common.cginc" -#include "./uDD_Params.cginc" v2f vert(appdata v) { @@ -32,7 +31,7 @@ v2f vert(appdata v) fixed4 frag(v2f i) : SV_Target { - return fixed4(uddGetScreenTextureWithCursor(_MainTex, _CursorTex, i.uv, _CursorPositionScale).rgb, 1.0) * _Color; + return fixed4(uddGetScreenTextureWithCursor(i.uv).rgb, 1.0) * _Color; } ENDCG @@ -44,8 +43,9 @@ Pass #pragma fragment frag #pragma multi_compile ___ INVERT_X #pragma multi_compile ___ INVERT_Y - #pragma multi_compile ___ VERTICAL #pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270 + #pragma multi_compile ___ USE_BEND + #pragma multi_compile ___ USE_CLIP ENDCG } diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp index d2f0035..9d882d5 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp @@ -38,7 +38,8 @@ void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) isVisible_ = frameInfo.PointerPosition.Visible != 0; timestamp_ = frameInfo.LastMouseUpdateTime; - if (frameInfo.PointerPosition.Visible != 0) { + if (isVisible_) + { GetMonitorManager()->SetCursorMonitorId(monitor_->GetId()); } diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp index ef8daac..8806f27 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp @@ -72,8 +72,6 @@ HRESULT Monitor::Render(UINT timeout) return S_OK; } - if (unityTexture_ == nullptr) return 0; - IDXGIResource* resource = nullptr; DXGI_OUTDUPL_FRAME_INFO frameInfo; @@ -97,18 +95,22 @@ HRESULT Monitor::Render(UINT timeout) return hr; } - ID3D11Texture2D* texture; - resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast(&texture)); + if (unityTexture_) + { + ID3D11Texture2D* texture; + resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast(&texture)); - ID3D11DeviceContext* context; - GetDevice()->GetImmediateContext(&context); - context->CopyResource(unityTexture_, texture); - context->Release(); + ID3D11DeviceContext* context; + GetDevice()->GetImmediateContext(&context); + context->CopyResource(unityTexture_, texture); + context->Release(); + + resource->Release(); + } cursor_->UpdateBuffer(frameInfo); cursor_->UpdateTexture(); - resource->Release(); deskDupl_->ReleaseFrame(); return S_OK; diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/main.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/main.cpp index 4c03f6c..38699c7 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/main.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/main.cpp @@ -118,6 +118,12 @@ extern "C" return g_manager->GetMonitorCount(); } + UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorMonitorId() + { + if (!g_manager) return -1; + return g_manager->GetCursorMonitorId(); + } + UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetTotalWidth() { if (!g_manager) return 0;