Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f74221bf75 | ||
|
|
3a705732d1 | ||
|
|
804bfb96bd | ||
|
|
63d8f6936d | ||
|
|
e4e4917bcb | ||
|
|
0e205ecef7 | ||
|
|
cda8024b17 | ||
|
|
05085f7d24 | ||
|
|
52eafbe919 | ||
|
|
be1e0c25bb |
Binary file not shown.
BIN
Assets/uDesktopDuplication/Examples/Prefabs/Monitor Plane.prefab
Normal file
BIN
Assets/uDesktopDuplication/Examples/Prefabs/Monitor Plane.prefab
Normal file
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42d6b6dbae38a384e882c2c907915139
|
||||
timeCreated: 1478889784
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -9,12 +9,16 @@ public class MultipleMonitorCreator : MonoBehaviour
|
||||
bool hasMonitorUnsupportStateChecked = false;
|
||||
float removeWaitTimer_ = 0f;
|
||||
|
||||
public enum MeshForwardDirection { Y, Z }
|
||||
[Tooltip("Please specify the upper vector direction of the mesh (e.g. Plane's upper direction is Y.)")]
|
||||
public MeshForwardDirection meshForwardDirection = MeshForwardDirection.Z;
|
||||
|
||||
public class MonitorInfo
|
||||
{
|
||||
public GameObject gameObject { get; set; }
|
||||
public Quaternion originalRotation { get; set; }
|
||||
public uDesktopDuplication.Texture uddTexture { get; set; }
|
||||
public Vector3 meshBounds;
|
||||
public Mesh mesh { get; set; }
|
||||
}
|
||||
|
||||
private List<MonitorInfo> monitors_ = new List<MonitorInfo>();
|
||||
@@ -22,6 +26,7 @@ public class MultipleMonitorCreator : MonoBehaviour
|
||||
|
||||
void Start()
|
||||
{
|
||||
uDesktopDuplication.Manager.CreateInstance();
|
||||
Create();
|
||||
}
|
||||
|
||||
@@ -68,38 +73,45 @@ public class MultipleMonitorCreator : MonoBehaviour
|
||||
{
|
||||
ResetRemoveTimer();
|
||||
|
||||
// Sort monitors in coordinate order
|
||||
var monitors = uDesktopDuplication.Manager.monitors;
|
||||
monitors.Sort((a, b) => a.left - b.left);
|
||||
|
||||
// Create monitors
|
||||
for (int i = 0; i < uDesktopDuplication.Manager.monitorCount; ++i) {
|
||||
// Create monitor obeject
|
||||
var go = Instantiate(monitorPrefab);
|
||||
go.name = "Monitor " + i;
|
||||
|
||||
// Expand AABB
|
||||
var mesh = go.GetComponent<MeshFilter>().mesh; // clone
|
||||
var aabbScale = mesh.bounds.size;
|
||||
aabbScale.y = Mathf.Max(aabbScale.y, aabbScale.x);
|
||||
aabbScale.z = Mathf.Max(aabbScale.z, aabbScale.x);
|
||||
mesh.bounds = new Bounds(mesh.bounds.center, aabbScale);
|
||||
|
||||
// Assign monitor
|
||||
var texture = go.GetComponent<uDesktopDuplication.Texture>();
|
||||
texture.monitorId = i;
|
||||
var monitor = texture.monitor;
|
||||
|
||||
// Set width / height
|
||||
go.transform.localScale = new Vector3(monitor.widthMeter, go.transform.localScale.y, monitor.heightMeter);
|
||||
if (meshForwardDirection == MeshForwardDirection.Y) {
|
||||
go.transform.localScale = new Vector3(monitor.widthMeter, go.transform.localScale.y, monitor.heightMeter);
|
||||
} else {
|
||||
go.transform.localScale = new Vector3(monitor.widthMeter, monitor.heightMeter, go.transform.localScale.z);
|
||||
}
|
||||
|
||||
// Set parent as this object
|
||||
go.transform.SetParent(transform);
|
||||
|
||||
// Calc actual size considering mesh size
|
||||
var bounds = go.GetComponent<MeshFilter>().sharedMesh.bounds.extents * 2f;
|
||||
|
||||
// Save
|
||||
var info = new MonitorInfo();
|
||||
info.gameObject = go;
|
||||
info.originalRotation = go.transform.rotation;
|
||||
info.uddTexture = texture;
|
||||
info.meshBounds = bounds;
|
||||
info.mesh = mesh;
|
||||
monitors_.Add(info);
|
||||
}
|
||||
|
||||
// Sort monitors in coordinate order
|
||||
monitors_.Sort((a, b) => a.uddTexture.monitor.left - b.uddTexture.monitor.left);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
|
||||
@@ -15,13 +15,13 @@ public class MultipleMonitorLayouter : MonoBehaviour
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (updateEveryFrame) {
|
||||
Layout();
|
||||
if (updateEveryFrame) {
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
{
|
||||
margin = Mathf.Max(margin, 0f);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class MultipleMonitorLayouter : MonoBehaviour
|
||||
|
||||
var totalWidth = 0f;
|
||||
foreach (var info in monitors) {
|
||||
var width = info.uddTexture.monitor.widthMeter * info.meshBounds.x;
|
||||
var width = info.uddTexture.monitor.widthMeter * (info.mesh.bounds.extents.x * 2f);
|
||||
totalWidth += width;
|
||||
}
|
||||
totalWidth += margin * (n - 1);
|
||||
@@ -41,10 +41,10 @@ public class MultipleMonitorLayouter : MonoBehaviour
|
||||
|
||||
foreach (var info in creator_.monitors) {
|
||||
var monitor = info.uddTexture.monitor;
|
||||
x += (monitor.widthMeter * info.meshBounds.x) / 2;
|
||||
x += (monitor.widthMeter * info.mesh.bounds.extents.x);
|
||||
info.gameObject.transform.localPosition = new Vector3(x, 0f, 0f);
|
||||
info.gameObject.transform.localRotation = info.originalRotation;
|
||||
x += (monitor.widthMeter * info.meshBounds.x) / 2 + margin;
|
||||
x += (monitor.widthMeter * info.mesh.bounds.extents.x) + margin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
|
||||
|
||||
var totalWidth = 0f;
|
||||
foreach (var info in monitors) {
|
||||
var width = info.uddTexture.monitor.widthMeter * info.meshBounds.x;
|
||||
var width = info.uddTexture.monitor.widthMeter * (info.mesh.bounds.extents.x * 2f);
|
||||
totalWidth += width;
|
||||
}
|
||||
totalWidth += margin * (n - 1);
|
||||
@@ -29,16 +29,20 @@ public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
|
||||
float angle = -totalAngle / 2;
|
||||
foreach (var info in monitors) {
|
||||
var uddTex = info.uddTexture;
|
||||
var width = uddTex.monitor.widthMeter * info.meshBounds.x;
|
||||
var width = uddTex.monitor.widthMeter * (info.mesh.bounds.extents.x * 2f);
|
||||
|
||||
angle += (width / radius) * 0.5f;
|
||||
uddTex.transform.localPosition = radius * new Vector3(Mathf.Sin(angle), 0f, Mathf.Cos(angle) - 1f);
|
||||
uddTex.transform.localRotation = Quaternion.AngleAxis(angle * Mathf.Rad2Deg, Vector3.up) * info.originalRotation;
|
||||
angle += (width * 0.5f + margin) / radius;
|
||||
|
||||
uddTex.bend = uDesktopDuplication.Texture.Bend.Y;
|
||||
if (creator_.meshForwardDirection == MultipleMonitorCreator.MeshForwardDirection.Y) {
|
||||
uddTex.bend = uDesktopDuplication.Texture.Bend.Y;
|
||||
} else {
|
||||
uddTex.bend = uDesktopDuplication.Texture.Bend.Z;
|
||||
}
|
||||
uddTex.radius = radius;
|
||||
uddTex.width = uddTex.monitor.widthMeter;
|
||||
uddTex.width = uddTex.transform.localScale.x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
9
Assets/uDesktopDuplication/Models.meta
Normal file
9
Assets/uDesktopDuplication/Models.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75494e992a22ea44d9b614d7fd3dc235
|
||||
folderAsset: yes
|
||||
timeCreated: 1478887431
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/uDesktopDuplication/Models/uDD_Board.fbx
Normal file
BIN
Assets/uDesktopDuplication/Models/uDD_Board.fbx
Normal file
Binary file not shown.
78
Assets/uDesktopDuplication/Models/uDD_Board.fbx.meta
Normal file
78
Assets/uDesktopDuplication/Models/uDD_Board.fbx.meta
Normal file
@@ -0,0 +1,78 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6b30b913257fee4d8246bf7a2620fcd
|
||||
timeCreated: 1478887431
|
||||
licenseType: Pro
|
||||
ModelImporter:
|
||||
serializedVersion: 19
|
||||
fileIDToRecycleName:
|
||||
100000: //RootNode
|
||||
400000: //RootNode
|
||||
2300000: //RootNode
|
||||
3300000: //RootNode
|
||||
4300000: pCube1
|
||||
4300002: uDD_Board
|
||||
9500000: //RootNode
|
||||
materials:
|
||||
importMaterials: 0
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
clipAnimations: []
|
||||
isReadable: 0
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 0.1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importBlendShapes: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 2
|
||||
importAnimation: 0
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 0
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 37 KiB |
@@ -85,6 +85,8 @@ public static class Lib
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern IntPtr GetRenderEventFunc();
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern int GetId(int id);
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern MonitorState GetState(int id);
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern void GetName(int id, StringBuilder buf, int len);
|
||||
|
||||
@@ -11,21 +11,7 @@ public class Manager : MonoBehaviour
|
||||
private static Manager instance_;
|
||||
public static Manager instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance_) {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
var manager = FindObjectOfType<Manager>();
|
||||
if (manager) {
|
||||
manager.Awake();
|
||||
return manager;
|
||||
}
|
||||
|
||||
var go = new GameObject("uDesktopDuplicationManager");
|
||||
return go.AddComponent<Manager>();
|
||||
}
|
||||
get { return CreateInstance(); }
|
||||
}
|
||||
|
||||
private List<Monitor> monitors_ = new List<Monitor>();
|
||||
@@ -63,6 +49,22 @@ public class Manager : MonoBehaviour
|
||||
public delegate void ReinitializeHandler();
|
||||
public static event ReinitializeHandler onReinitialized;
|
||||
|
||||
public static Manager CreateInstance()
|
||||
{
|
||||
if (instance_) {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
var manager = FindObjectOfType<Manager>();
|
||||
if (manager) {
|
||||
manager.Awake();
|
||||
return manager;
|
||||
}
|
||||
|
||||
var go = new GameObject("uDesktopDuplicationManager");
|
||||
return go.AddComponent<Manager>();
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
Lib.SetDebugMode(debugMode);
|
||||
|
||||
@@ -13,8 +13,9 @@ public class Texture : MonoBehaviour
|
||||
set
|
||||
{
|
||||
monitor_ = value;
|
||||
material = GetComponent<Renderer>().material;
|
||||
material = GetComponent<Renderer>().material; // clone
|
||||
material.mainTexture = monitor_.texture;
|
||||
material.SetFloat("_Width", transform.localScale.x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,4 +92,19 @@ inline fixed4 uddGetScreenTextureWithCursor(float2 uv)
|
||||
return color;
|
||||
}
|
||||
|
||||
inline void uddBendVertex(inout float4 v, half radius, half width)
|
||||
{
|
||||
#if !defined(_BEND_OFF)
|
||||
half angle = width * v.x / radius;
|
||||
#ifdef _BEND_Y
|
||||
radius -= v.y;
|
||||
v.y += radius * (1 - cos(angle));
|
||||
#elif _BEND_Z
|
||||
radius -= v.z;
|
||||
v.z += radius * (1 - cos(angle));
|
||||
#endif
|
||||
v.x = radius * sin(angle) / width;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,7 +7,7 @@ Properties
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
_CursorTex ("Cursor Texture", 2D) = "white" {}
|
||||
[KeywordEnum(Off, Y, Z)] _Bend("Bending", Int) = 0
|
||||
[PowerSlider(10.0)]_Radius ("Radius", Range(1, 100)) = 30
|
||||
[PowerSlider(10.0)] _Radius("Radius", Range(1, 100)) = 30
|
||||
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
|
||||
}
|
||||
|
||||
@@ -28,15 +28,7 @@ half _Width;
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
#if defined(_BEND_Z) || defined(_BEND_Y)
|
||||
half a = _Width * v.vertex.x / _Radius;
|
||||
v.vertex.x = _Radius * sin(a) / _Width;
|
||||
#ifdef _BEND_Y
|
||||
v.vertex.y += _Radius * (1 - cos(a));
|
||||
#elif _BEND_Z
|
||||
v.vertex.z += _Radius * (1 - cos(a));
|
||||
#endif
|
||||
#endif
|
||||
uddBendVertex(v.vertex, _Radius, _Width);
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
return o;
|
||||
|
||||
@@ -6,6 +6,9 @@ Properties
|
||||
_Color ("Color", Color) = (1, 1, 1, 1)
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
_Mask ("Mask", Range(0, 1)) = 0.1
|
||||
_CursorTex ("Cursor Texture", 2D) = "white" {}
|
||||
[KeywordEnum(Off, Y, Z)] _Bend("Bending", Int) = 0
|
||||
[PowerSlider(10.0)] _Radius("Radius", Range(1, 100)) = 30
|
||||
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
|
||||
}
|
||||
|
||||
@@ -23,10 +26,13 @@ CGINCLUDE
|
||||
#include "./uDD_Common.cginc"
|
||||
|
||||
fixed _Mask;
|
||||
half _Radius;
|
||||
half _Width;
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
uddBendVertex(v.vertex, _Radius, _Width);
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
return o;
|
||||
@@ -51,6 +57,7 @@ Pass
|
||||
#pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270
|
||||
#pragma multi_compile ___ USE_BEND
|
||||
#pragma multi_compile ___ USE_CLIP
|
||||
#pragma multi_compile _BEND_OFF _BEND_Y _BEND_Z
|
||||
ENDCG
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ Properties
|
||||
{
|
||||
_Color ("Color", Color) = (1, 1, 1, 1)
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
_CursorTex ("Cursor Texture", 2D) = "white" {}
|
||||
[KeywordEnum(Off, Y, Z)] _Bend("Bending", Int) = 0
|
||||
[PowerSlider(10.0)] _Radius("Radius", Range(1, 100)) = 30
|
||||
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
|
||||
}
|
||||
|
||||
@@ -21,9 +24,13 @@ CGINCLUDE
|
||||
|
||||
#include "./uDD_Common.cginc"
|
||||
|
||||
half _Radius;
|
||||
half _Width;
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
uddBendVertex(v.vertex, _Radius, _Width);
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
return o;
|
||||
@@ -46,6 +53,7 @@ Pass
|
||||
#pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270
|
||||
#pragma multi_compile ___ USE_BEND
|
||||
#pragma multi_compile ___ USE_CLIP
|
||||
#pragma multi_compile _BEND_OFF _BEND_Y _BEND_Z
|
||||
ENDCG
|
||||
}
|
||||
|
||||
|
||||
@@ -13,18 +13,6 @@ struct ID3D11Device;
|
||||
ID3D11Device* GetDevice();
|
||||
|
||||
|
||||
// Utility
|
||||
template <class T>
|
||||
auto MakeUniqueWithReleaser(T* ptr)
|
||||
{
|
||||
const auto deleter = [](T* ptr)
|
||||
{
|
||||
if (ptr != nullptr) ptr->Release();
|
||||
};
|
||||
return std::unique_ptr<T, decltype(deleter)>(ptr, deleter);
|
||||
}
|
||||
|
||||
|
||||
// Manager getter
|
||||
class MonitorManager;
|
||||
const std::unique_ptr<MonitorManager>& GetMonitorManager();
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
#include "Common.h"
|
||||
#include "Debug.h"
|
||||
#include "MonitorManager.h"
|
||||
#include "Monitor.h"
|
||||
#include "Cursor.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
Cursor::Cursor(Monitor* monitor)
|
||||
: monitor_(monitor)
|
||||
@@ -24,16 +27,16 @@ void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||
return;
|
||||
}
|
||||
|
||||
x_ = frameInfo.PointerPosition.Position.x;
|
||||
y_ = frameInfo.PointerPosition.Position.y;
|
||||
isVisible_ = frameInfo.PointerPosition.Visible != 0;
|
||||
timestamp_ = frameInfo.LastMouseUpdateTime;
|
||||
|
||||
if (isVisible_)
|
||||
{
|
||||
GetMonitorManager()->SetCursorMonitorId(monitor_->GetId());
|
||||
}
|
||||
|
||||
x_ = frameInfo.PointerPosition.Position.x;
|
||||
y_ = frameInfo.PointerPosition.Position.y;
|
||||
timestamp_ = frameInfo.LastMouseUpdateTime;
|
||||
|
||||
if (!IsCursorOnParentMonitor())
|
||||
{
|
||||
return;
|
||||
@@ -149,9 +152,8 @@ void Cursor::UpdateTexture()
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
ID3D11Texture2D* texture = nullptr;
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
hr = GetDevice()->CreateTexture2D(&desc, nullptr, &texture);
|
||||
const auto textureReleaser = MakeUniqueWithReleaser(texture);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => GetDevice()->CreateTexture2D() failed.");
|
||||
@@ -172,14 +174,14 @@ void Cursor::UpdateTexture()
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture, 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
|
||||
context->Release();
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
|
||||
}
|
||||
|
||||
IDXGISurface* surface = nullptr;
|
||||
hr = texture->QueryInterface(__uuidof(IDXGISurface), (void**)&surface);
|
||||
const auto surfaceReleaser = MakeUniqueWithReleaser(surface);
|
||||
ComPtr<IDXGISurface> surface;
|
||||
hr = texture.As<IDXGISurface>(&surface);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => texture->QueryInterface() failed.");
|
||||
@@ -286,10 +288,9 @@ void Cursor::GetTexture(ID3D11Texture2D* texture)
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* context;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->UpdateSubresource(texture, 0, nullptr, bgra32Buffer_.get(), GetWidth() * 4, 0);
|
||||
context->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "MonitorManager.h"
|
||||
#include "Monitor.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
Monitor::Monitor(int id)
|
||||
: id_(id)
|
||||
@@ -28,17 +30,14 @@ void Monitor::Initialize(IDXGIOutput* output)
|
||||
GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_);
|
||||
|
||||
auto output1 = reinterpret_cast<IDXGIOutput1*>(output);
|
||||
IDXGIOutputDuplication* deskDupl;
|
||||
const auto hr = output1->DuplicateOutput(GetDevice(), &deskDupl);
|
||||
deskDupl_ = std::shared_ptr<IDXGIOutputDuplication>(
|
||||
deskDupl,
|
||||
[](IDXGIOutputDuplication* ptr) { ptr->Release(); });
|
||||
const auto hr = output1->DuplicateOutput(GetDevice(), &deskDupl_);
|
||||
|
||||
// TODO: error check
|
||||
switch (hr)
|
||||
{
|
||||
case S_OK:
|
||||
state_ = State::Available;
|
||||
Debug::Log("Monitor::Initialize() => OK.");
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
state_ = State::InvalidArg;
|
||||
@@ -73,12 +72,11 @@ void Monitor::Render(UINT timeout)
|
||||
{
|
||||
if (!deskDupl_) return;
|
||||
|
||||
IDXGIResource* resource = nullptr;
|
||||
ComPtr<IDXGIResource> resource;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
HRESULT hr;
|
||||
|
||||
hr = deskDupl_->AcquireNextFrame(timeout, &frameInfo, &resource);
|
||||
const auto resourceReleaser = MakeUniqueWithReleaser(resource);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
switch (hr)
|
||||
@@ -107,13 +105,12 @@ void Monitor::Render(UINT timeout)
|
||||
|
||||
if (unityTexture_)
|
||||
{
|
||||
ID3D11Texture2D* texture;
|
||||
resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&texture));
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
resource.As<ID3D11Texture2D>(&texture);
|
||||
|
||||
ID3D11DeviceContext* context;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(unityTexture_, texture);
|
||||
context->Release();
|
||||
context->CopyResource(unityTexture_, texture.Get());
|
||||
}
|
||||
|
||||
cursor_->UpdateBuffer(frameInfo);
|
||||
@@ -151,7 +148,7 @@ ID3D11Texture2D* Monitor::GetUnityTexture() const
|
||||
}
|
||||
|
||||
|
||||
const std::shared_ptr<IDXGIOutputDuplication>& Monitor::GetDeskDupl()
|
||||
const ComPtr<IDXGIOutputDuplication>& Monitor::GetDeskDupl()
|
||||
{
|
||||
return deskDupl_;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <wrl/client.h>
|
||||
#include <memory>
|
||||
|
||||
class Cursor;
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
int GetRotation() const;
|
||||
int GetDpiX() const;
|
||||
int GetDpiY() const;
|
||||
const std::shared_ptr<IDXGIOutputDuplication>& GetDeskDupl();
|
||||
const Microsoft::WRL::ComPtr<IDXGIOutputDuplication>& GetDeskDupl();
|
||||
const std::unique_ptr<Cursor>& GetCursor();
|
||||
|
||||
private:
|
||||
@@ -53,7 +54,7 @@ private:
|
||||
UINT dpiX_ = -1, dpiY_ = -1;
|
||||
State state_ = State::NotSet;
|
||||
std::unique_ptr<Cursor> cursor_;
|
||||
std::shared_ptr<IDXGIOutputDuplication> deskDupl_;
|
||||
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> deskDupl_;
|
||||
ID3D11Texture2D* unityTexture_ = nullptr;
|
||||
DXGI_OUTPUT_DESC outputDesc_;
|
||||
MONITORINFOEX monitorInfo_;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <wrl/client.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
@@ -12,6 +13,8 @@
|
||||
#include "Cursor.h"
|
||||
#include "MonitorManager.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
MonitorManager::MonitorManager()
|
||||
{
|
||||
@@ -30,23 +33,20 @@ void MonitorManager::Initialize()
|
||||
Finalize();
|
||||
|
||||
// Get factory
|
||||
IDXGIFactory1* factory;
|
||||
CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&factory));
|
||||
const auto factoryReleaser = MakeUniqueWithReleaser(factory);
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
CreateDXGIFactory1(IID_PPV_ARGS(&factory));
|
||||
|
||||
// Check all display adapters
|
||||
int id = 0;
|
||||
IDXGIAdapter1* adapter;
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
||||
{
|
||||
const auto adapterReleaser = MakeUniqueWithReleaser(adapter);
|
||||
// Search the main monitor from all outputs
|
||||
IDXGIOutput* output;
|
||||
ComPtr<IDXGIOutput> output;
|
||||
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
||||
{
|
||||
const auto outputReleaser = MakeUniqueWithReleaser(output);
|
||||
auto monitor = std::make_shared<Monitor>(id++);
|
||||
monitor->Initialize(output);
|
||||
monitor->Initialize(output.Get());
|
||||
monitors_.push_back(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,15 @@ extern "C"
|
||||
g_manager->SetTimeout(timeout);
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API GetId(int id)
|
||||
{
|
||||
if (!g_manager) return;
|
||||
if (auto monitor = g_manager->GetMonitor(id))
|
||||
{
|
||||
monitor->GetId();
|
||||
}
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT MonitorState UNITY_INTERFACE_API GetState(int id)
|
||||
{
|
||||
if (!g_manager) return MonitorState::NotSet;
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user