fetch cursor texture.

This commit is contained in:
hecomi
2016-11-01 02:15:25 +09:00
parent 9287ef2f2d
commit 6ba381f5d4
11 changed files with 905 additions and 70 deletions
+76 -18
View File
@@ -7,35 +7,93 @@ namespace uDesktopDuplication
RequireComponent(typeof(Texture))]
public class Cursor : MonoBehaviour
{
[SerializeField]
Transform cursor;
[SerializeField]
Vector2 modelScale = Vector2.one;
[SerializeField]
Vector2 offset = new Vector2(0.5f, 0.5f);
[SerializeField] Vector2 modelScale = Vector2.one;
private Texture texture_;
Vector3 worldPosition { get; set; }
private Texture uddTexture_;
private Monitor monitor { get { return uddTexture_.monitor; } }
private Texture2D pointerTexture_;
private Material cursorMaterial_;
void OnEnable()
{
texture_ = GetComponent<Texture>();
uddTexture_ = GetComponent<Texture>();
}
void Start()
{
var clone = new GameObject(name + " Cursor");
clone.transform.SetParent(transform);
clone.transform.localPosition = Vector3.zero;
clone.transform.localRotation = Quaternion.identity;
clone.transform.localScale = Vector3.one;
var filter = clone.AddComponent<MeshFilter>();
filter.mesh = GetComponent<MeshFilter>().sharedMesh;
var renderer = clone.AddComponent<MeshRenderer>();
var shader = Shader.Find("uDesktopDuplication/Cursor");
cursorMaterial_ = new Material(shader);
renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
renderer.receiveShadows = false;
renderer.motionVectors = false;
renderer.material = cursorMaterial_;
}
void Update()
{
var monitor = texture_.monitor;
if (monitor.isPointerVisible) {
var x = (1f * monitor.pointerX / monitor.width - 0.5f) * modelScale.x;
var y = (0.5f - 1f * monitor.pointerY / monitor.height) * modelScale.y;
var iy = texture_.invertY ? +1 : -1;
var localPos = transform.right * x + iy * transform.up * y;
var worldPos = transform.TransformPoint(localPos);
worldPos += cursor.right * offset.x * cursor.localScale.x;
worldPos += -cursor.up * offset.y * cursor.localScale.y;
worldPos += -cursor.forward * 0.001f;
cursor.position = worldPos;
UpdatePosition();
UpdateTexture();
UpdateMaterial();
}
}
void UpdatePosition()
{
var x = (1f * monitor.pointerX / monitor.width - 0.5f) * modelScale.x;
var y = (1f * monitor.pointerY / monitor.height - 0.5f) * modelScale.y;
var iy = uddTexture_.invertY ? -1 : +1;
var localPos = transform.right * x + iy * transform.up * y;
worldPosition = transform.TransformPoint(localPos);
}
void UpdateTexture()
{
pointerTexture_ = new Texture2D(monitor.pointerShapeWidth, monitor.pointerShapeHeight, TextureFormat.BGRA32, false);
pointerTexture_.wrapMode = TextureWrapMode.Clamp;
monitor.UpdatePointerTexture(pointerTexture_.GetNativeTexturePtr());
cursorMaterial_.SetTexture("_MainTex", pointerTexture_);
}
void UpdateMaterial()
{
if (uddTexture_.invertX) {
cursorMaterial_.EnableKeyword("INVERT_X");
} else {
cursorMaterial_.DisableKeyword("INVERT_X");
}
if (uddTexture_.invertY) {
cursorMaterial_.EnableKeyword("INVERT_Y");
} else {
cursorMaterial_.DisableKeyword("INVERT_Y");
}
if (monitor.isVertical) {
cursorMaterial_.EnableKeyword("VERTICAL");
} else {
cursorMaterial_.DisableKeyword("VERTICAL");
}
var x = (float)monitor.pointerX / monitor.width;
var y = (float)monitor.pointerY / monitor.height;
var w = (float)monitor.pointerShapeWidth / monitor.width;
var h = (float)monitor.pointerShapeHeight / monitor.height;
cursorMaterial_.SetVector("_PositionScale", new Vector4(x, y, w, h));
}
}
}
+26
View File
@@ -5,6 +5,13 @@ using System.Runtime.InteropServices;
namespace uDesktopDuplication
{
public enum PointerShapeType
{
MonoChrome = 1,
Color = 2,
MaskedColor = 4,
}
public static class Lib
{
[DllImport("uDesktopDuplication")]
@@ -28,9 +35,21 @@ public static class Lib
[DllImport("uDesktopDuplication")]
public static extern int GetPointerY(int id);
[DllImport("uDesktopDuplication")]
public static extern int GetPointerShapeWidth(int id);
[DllImport("uDesktopDuplication")]
public static extern int GetPointerShapeHeight(int id);
[DllImport("uDesktopDuplication")]
public static extern int GetPointerShapePitch(int id);
[DllImport("uDesktopDuplication")]
public static extern PointerShapeType GetPointerShapeType(int id);
[DllImport("uDesktopDuplication")]
public static extern void UpdatePointerTexture(int id, System.IntPtr ptr);
[DllImport("uDesktopDuplication")]
public static extern int SetTexturePtr(int id, IntPtr ptr);
[DllImport("uDesktopDuplication")]
public static extern int GetErrorCode();
[DllImport("uDesktopDuplication")]
public static extern void GetErrorMessage(StringBuilder buf, int len);
public static string GetName(int id)
{
@@ -38,6 +57,13 @@ public static class Lib
GetName(id, buf, buf.Capacity);
return buf.ToString();
}
public static string GetErrorMessage()
{
var buf = new StringBuilder(64);
GetErrorMessage(buf, buf.Capacity);
return buf.ToString();
}
}
}
@@ -40,6 +40,9 @@ public class Manager : MonoBehaviour
[SerializeField, Tooltip("Set Desktop Duplication API timeout (milliseconds).")]
int timeout = 0;
[SerializeField, Tooltip("Output logs given by the plugin.")]
bool outputDebugLog = false;
private Coroutine renderCoroutine_ = null;
void Awake()
@@ -78,6 +81,10 @@ public class Manager : MonoBehaviour
}
monitor.shouldBeUpdated = false;
}
if (outputDebugLog && Lib.GetErrorCode() != 0)
{
Debug.Log(Lib.GetErrorMessage());
}
}
}
}
@@ -66,6 +66,21 @@ public class Monitor
get { return Lib.GetPointerY(id); }
}
public int pointerShapeWidth
{
get { return Lib.GetPointerShapeWidth(id); }
}
public int pointerShapeHeight
{
get { return Lib.GetPointerShapeHeight(id); }
}
public PointerShapeType pointerShapeType
{
get { return Lib.GetPointerShapeType(id); }
}
public bool shouldBeUpdated
{
get;
@@ -91,6 +106,11 @@ public class Monitor
{
GL.IssuePluginEvent(Lib.GetRenderEventFunc(), id);
}
public void UpdatePointerTexture(System.IntPtr ptr)
{
Lib.UpdatePointerTexture(id, ptr);
}
}
}
@@ -18,13 +18,18 @@ inline void uddInvertUV(inout float2 uv)
#endif
}
inline void uddToLinearIfNeeded(inout float3 rgb)
{
if (!IsGammaSpace()) {
rgb = GammaToLinearSpace(rgb);
}
}
inline fixed4 uddGetTexture(sampler2D tex, float2 uv)
{
uddInvertUV(uv);
fixed4 c = tex2D(tex, uv);
if (!IsGammaSpace()) {
c.rgb = GammaToLinearSpace(c.rgb);
}
uddToLinearIfNeeded(c.rgb);
return c;
}
@@ -0,0 +1,79 @@
Shader "uDesktopDuplication/Cursor"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
ZWrite Off
Offset -1, -1
CGINCLUDE
#include "UnityCG.cginc"
#include "./uDD_Common.cginc"
half4 _PositionScale;
#define _PointerX _PositionScale.x
#define _PointerY _PositionScale.y
#define _PointerWidth _PositionScale.z
#define _PointerHeight _PositionScale.w
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
uddInvertUV(i.uv);
i.uv.x = (i.uv.x - _PointerX) / _PointerWidth;
i.uv.y = (i.uv.y - _PointerY) / _PointerHeight;
fixed4 color = tex2D(_MainTex, i.uv);
color.a *= step(0, i.uv.x) * step(0, i.uv.y) * step(i.uv.x, 1) * step(i.uv.y, 1);
clip(color.a - 0.01);
uddToLinearIfNeeded(color.rgb);
return color;
}
ENDCG
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile ___ INVERT_X
#pragma multi_compile ___ INVERT_Y
#pragma multi_compile ___ VERTICAL
ENDCG
}
}
Fallback "Unlit/Texture"
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d224cadaa1bfa2d46a6224ce2a1443c7
timeCreated: 1477847636
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant: