-
-
Save smakhtin/08c8eaae8e5db470685e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Emgu.CV; | |
using System.Drawing; | |
using SlimDX.Direct3D9; | |
using SlimDX; | |
using VVVV.Utils.SlimDX; | |
using FeralTic.DX11.Resources; | |
using FeralTic.DX11; | |
namespace VVVV.Nodes.OpenCV | |
{ | |
class AsDX11TextureInstance : IDestinationInstance | |
{ | |
// [DllImport("msvcrt.dll", EntryPoint = "memcpy")] | |
// public unsafe static extern void CopyMemory(IntPtr pDest, IntPtr pSrc, int length); | |
public int Width { get; private set; } | |
public int Height { get; private set; } | |
CVImageDoubleBuffer FBufferConverted; | |
TColorFormat FConvertedFormat; | |
bool FNeedsConversion = false; | |
Object FLockTexture = new Object(); | |
private Dictionary<DX11DynamicTexture2D, bool> FNeedsRefresh = new Dictionary<DX11DynamicTexture2D, bool>(); | |
private bool FNeedsTexture = false; | |
public bool NeedsTexture | |
{ | |
get | |
{ | |
if (FNeedsTexture) | |
{ | |
FNeedsTexture = false; | |
return true; | |
} | |
return false; | |
} | |
} | |
public override void Allocate() | |
{ | |
FNeedsConversion = ImageUtils.NeedsConversion(FInput.ImageAttributes.ColourFormat, out FConvertedFormat); | |
if (FNeedsConversion) | |
{ | |
FBufferConverted = new CVImageDoubleBuffer(); | |
FBufferConverted.Initialise(new CVImageAttributes(FInput.ImageAttributes.Size, FConvertedFormat)); | |
} | |
FNeedsTexture = true; | |
} | |
public override void Process() | |
{ | |
lock (FLockTexture) | |
{ | |
//ImageChanged so mark needs refresh on created textures | |
foreach (var key in FNeedsRefresh.Keys.ToList()) | |
{ | |
FNeedsRefresh[key] = true; | |
} | |
} | |
if (FNeedsConversion) | |
{ | |
FInput.GetImage(FBufferConverted); | |
FBufferConverted.Swap(); | |
} | |
} | |
private bool InputOK | |
{ | |
get | |
{ | |
if (FNeedsConversion) | |
{ | |
if (FBufferConverted == null) | |
return false; | |
if (!FBufferConverted.Allocated) | |
return false; | |
} | |
else | |
{ | |
if (FInput == null) | |
return false; | |
if (!FInput.Allocated) | |
return false; | |
} | |
return true; | |
} | |
} | |
private SlimDX.DXGI.Format GetFormat(TColorFormat format) | |
{ | |
switch (format) | |
{ | |
case TColorFormat.L16 : | |
return SlimDX.DXGI.Format.R16_UNorm; | |
case TColorFormat.L32F: | |
return SlimDX.DXGI.Format.R32_Float; | |
case TColorFormat.RGB8: | |
return SlimDX.DXGI.Format.R8G8B8A8_UNorm; | |
case TColorFormat.RGBA8: | |
return SlimDX.DXGI.Format.R8G8B8A8_UNorm; | |
case TColorFormat.RGB32F: | |
return SlimDX.DXGI.Format.R32G32B32A32_Float; | |
case TColorFormat.RGBA32F: | |
return SlimDX.DXGI.Format.R32G32B32A32_Float; | |
} | |
return SlimDX.DXGI.Format.Unknown; | |
} | |
public DX11DynamicTexture2D CreateTexture(DX11RenderContext context) | |
{ | |
lock (FLockTexture) | |
{ | |
if (InputOK) | |
{ | |
DX11DynamicTexture2D output; | |
if (FNeedsConversion) | |
{ | |
CVImageAttributes attr = FBufferConverted.ImageAttributes.Clone() as CVImageAttributes; | |
SlimDX.DXGI.Format format = this.GetFormat(attr.ColourFormat); | |
output = new DX11DynamicTexture2D(context, attr.Width, attr.Height, format); | |
} | |
else | |
{ | |
CVImageAttributes attr = FBufferConverted.ImageAttributes as CVImageAttributes; | |
SlimDX.DXGI.Format format = this.GetFormat(attr.ColourFormat); | |
output = new DX11DynamicTexture2D(context, attr.Width, attr.Height, format); | |
} | |
FNeedsRefresh.Add(output, true); | |
return output; | |
} | |
else | |
{ | |
return context.DefaultTextures.WhiteTexture; | |
} | |
} | |
} | |
public void UpdateTexture(DX11DynamicTexture2D texture) | |
{ | |
lock (FLockTexture) | |
{ | |
if (!InputOK) | |
return; | |
if (!FNeedsRefresh.ContainsKey(texture)) | |
{ | |
FNeedsTexture = true; | |
return; | |
} | |
if (!FNeedsRefresh[texture]) | |
return; | |
if (FInput.ImageAttributesChanged) | |
{ | |
//reset flag we just dropped | |
FInput.ImageAttributesChanged = true; | |
return; | |
} | |
/*Surface srf = texture.GetSurfaceLevel(0); | |
DataRectangle rect = srf.LockRectangle(LockFlags.None);*/ | |
try | |
{ | |
Size imageSize = FNeedsConversion ? FBufferConverted.ImageAttributes.Size : FInput.ImageAttributes.Size; | |
if (texture.Width != imageSize.Width || texture.Height != imageSize.Height) | |
{ | |
throw (new Exception("AsTextureInstance : srf dimensions don't match image dimensions")); | |
} | |
if (FNeedsConversion) | |
{ | |
FInput.GetImage(FBufferConverted); | |
FBufferConverted.Swap(); | |
FBufferConverted.LockForReading(); | |
try | |
{ | |
if (!FBufferConverted.FrontImage.Allocated) | |
throw (new Exception()); | |
texture.WriteData(FInput.Data, FInput.BytesPerFrame); | |
//rect.Data.WriteRange(FBufferConverted.FrontImage.Data, FBufferConverted.ImageAttributes.BytesPerFrame); | |
FNeedsRefresh[texture] = false; | |
} | |
catch (Exception e) | |
{ | |
ImageUtils.Log(e); | |
} | |
finally | |
{ | |
FBufferConverted.ReleaseForReading(); | |
} | |
} | |
else | |
{ | |
FInput.LockForReading(); | |
try | |
{ | |
texture.WriteData(FInput.Data, FInput.BytesPerFrame); | |
//rect.Data.WriteRange(FInput.Data, FInput.ImageAttributes.BytesPerFrame); | |
FNeedsRefresh[texture] = false; | |
} | |
catch (Exception e) | |
{ | |
ImageUtils.Log(e); | |
} | |
finally | |
{ | |
FInput.ReleaseForReading(); | |
} | |
} | |
} | |
catch (Exception e) | |
{ | |
throw (e); | |
} | |
finally | |
{ | |
//srf.UnlockRectangle(); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using VVVV.PluginInterfaces.V2; | |
using FeralTic.DX11.Resources; | |
using VVVV.Nodes.OpenCV; | |
using System.ComponentModel.Composition; | |
using VVVV.PluginInterfaces.V1; | |
using System.Drawing; | |
namespace VVVV.DX11.CVLink | |
{ | |
public class TestNoiseInstance : IStaticGeneratorInstance | |
{ | |
string FLoadedImage = ""; | |
Size FSize = new Size(32, 32); | |
float FRadius = 1; | |
Random FRandom = new Random(); | |
public override bool NeedsThread() | |
{ | |
return false; | |
} | |
public void Refresh() | |
{ | |
FOutput.Image.Initialise(FSize, TColorFormat.RGBA32F); | |
FillRandomValues(); | |
FOutput.Send(); | |
} | |
public int Dimension | |
{ | |
set | |
{ | |
if (value < 1) | |
value = 1; | |
if (value > 4096) | |
value = 4096; | |
double valueLog2 = Math.Log((double)value) / Math.Log(2.0d); | |
value = 1 << (int)valueLog2; | |
FSize.Width = value; | |
FSize.Height = value; | |
Refresh(); | |
} | |
} | |
private unsafe void FillRandomValues() | |
{ | |
float* xyzt = (float*)FOutput.Data.ToPointer(); | |
int width = FSize.Width; | |
int height = FSize.Height; | |
for (int i = 0; i < width * height; i++) | |
{ | |
*xyzt++ = ((float)FRandom.NextDouble() - 0.5f) * 2.0f * FRadius; | |
*xyzt++ = ((float)FRandom.NextDouble() - 0.5f) * 2.0f * FRadius; | |
*xyzt++ = ((float)FRandom.NextDouble() - 0.5f) * 2.0f * FRadius; | |
*xyzt++ = 1; | |
} | |
} | |
} | |
[PluginInfo(Name = "FromTexture", | |
Category = "EmguCV", | |
Version = "DX11", | |
Help = "Converts Texture to IPLImage", | |
Tags = "", Author = "vux")] | |
public unsafe class FromDX11TextureInstance : IGeneratorNode<TestNoiseInstance>, IPluginEvaluate, IDX11ResourceDataRetriever | |
{ | |
[Input("Texture In")] | |
Pin<DX11Resource<DX11Texture2D>> FTexIn; | |
[Input("Refresh", IsBang = true)] | |
ISpread<bool> FRefresh; | |
[Input("Dimension", DefaultValue = 32, MinValue = 1, MaxValue = 4096)] | |
IDiffSpread<int> FDimension; | |
/*[Output("Image",IsSingle=true)] | |
ISpread<CVImageLink> FPinOutImage;*/ | |
[Import()] | |
protected IPluginHost FHost; | |
bool FInitialised = false; | |
CVImageOutputSpread FOutputs; | |
public void Evaluate(int SpreadMax) | |
{ | |
if (this.FTexIn.PluginIO.IsConnected) | |
{ | |
if (this.RenderRequest != null) { this.RenderRequest(this, this.FHost); } | |
if (this.AssignedContext == null) { return; } | |
DX11Texture2D t = this.FTexIn[0][this.AssignedContext]; | |
} | |
} | |
public FeralTic.DX11.DX11RenderContext AssignedContext | |
{ | |
get; | |
set; | |
} | |
public event DX11RenderRequestDelegate RenderRequest; | |
protected override void Update(int InstanceCount, bool SpreadChanged) | |
{ | |
for (int i = 0; i < InstanceCount; i++) | |
if (FRefresh[i]) | |
FProcessor[i].Refresh(); | |
if (FDimension.IsChanged) | |
for (int i = 0; i < InstanceCount; i++) | |
FProcessor[i].Dimension = FDimension[i]; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using VideoInputSharp; | |
using VVVV.PluginInterfaces.V2; | |
using VVVV.PluginInterfaces.V1; | |
using FeralTic.DX11; | |
using FeralTic.DX11.Resources; | |
using System.Runtime.InteropServices; | |
namespace VVVV.DX11.Nodes | |
{ | |
[PluginInfo(Name="VideoIn",Category="DX11.Texture", Version="DShow")] | |
public unsafe class VideoInNode : IPluginEvaluate, IDX11ResourceProvider, IDisposable | |
{ | |
[Input("Width", DefaultValue =640)] | |
IDiffSpread<int> FInW; | |
[Input("Height", DefaultValue = 480)] | |
IDiffSpread<int> FInH; | |
[Input("Fps", DefaultValue = 30)] | |
IDiffSpread<int> FInFPS; | |
[Input("Device Id", Order = 500, MinValue = 0)] | |
IDiffSpread<int> FInDeviceId; | |
[Input("Reset", Order = 505, IsBang=true)] | |
IDiffSpread<bool> FInReset; | |
[Input("Enabled", Order = 501, MinValue = 0)] | |
IDiffSpread<bool> FInEnabled; | |
[Output("Texture Out", IsSingle = true)] | |
protected Pin<DX11Resource<DX11DynamicTexture2D>> FTextureOutput; | |
[Output("Width Out", DefaultValue = 640)] | |
ISpread<int> FOutW; | |
[Output("Height Out", DefaultValue = 480)] | |
ISpread<int> FOutH; | |
VideoInputSharp.Capture c; | |
bool invalidate = true; | |
bool copyframe = false; | |
private IntPtr data = IntPtr.Zero; | |
private IntPtr rgbadata = IntPtr.Zero; | |
private long size; | |
private int pixcount; | |
public void Evaluate(int SpreadMax) | |
{ | |
this.copyframe = false; | |
if (c == null || this.FInReset[0]) | |
{ | |
if (c != null) | |
{ | |
c.Close(); | |
} | |
if (this.data != IntPtr.Zero) | |
{ | |
Marshal.FreeCoTaskMem(this.data); | |
} | |
c = new Capture(); | |
c.Open(this.FInDeviceId[0], this.FInFPS[0], this.FInW[0], this.FInH[0]); | |
this.size = this.FInW[0] * this.FInH[0] * 4; | |
this.pixcount = this.FInW[0] * this.FInH[0]; | |
this.data = Marshal.AllocCoTaskMem(this.FInW[0] * this.FInH[0] * 3); | |
this.rgbadata = Marshal.AllocCoTaskMem((int)size); | |
this.invalidate = true; | |
} | |
if (this.FTextureOutput[0] == null) | |
{ | |
this.FTextureOutput[0] = new DX11Resource<DX11DynamicTexture2D>(); | |
} | |
if (c != null && this.FInEnabled[0]) | |
{ | |
this.c.GetPixels(this.data); | |
byte* brgb = (byte*) this.data.ToPointer(); | |
byte* brgba = (byte*)this.rgbadata.ToPointer(); | |
/*int cnt = 0; | |
int cnta = 0; | |
for (int i = 0; i < this.FInH[0]; i++) | |
{ | |
for (int j = 0; j < this.FInW[0]; j++) | |
{ | |
brgba[cnta] = brgb[cnt]; | |
brgba[cnta + 1] = brgb[cnt + 1]; | |
brgba[cnta + 2] = brgb[cnt + 2]; | |
cnta += 4; | |
cnt += 3; | |
} | |
}*/ | |
for (int i = 0; i < this.pixcount; i++) | |
{ | |
brgba[i * 4] = brgb[i * 3]; | |
brgba[i * 4 + 1] = brgb[i * 3 + 1]; | |
brgba[i * 4 + 2] = brgb[i * 3 + 2]; | |
} | |
this.copyframe = true; | |
try | |
{ | |
this.FOutW[0] = c.GetWidth(); | |
this.FOutH[0] = c.GetHeight(); | |
} | |
catch | |
{ | |
} | |
} | |
} | |
public void Update(IPluginIO pin, DX11RenderContext context) | |
{ | |
if (c != null) | |
{ | |
if (this.invalidate || !this.FTextureOutput[0].Contains(context)) | |
{ | |
try | |
{ | |
if (this.FTextureOutput[0].Contains(context)) | |
{ | |
this.FTextureOutput[0].Dispose(context); | |
} | |
DX11DynamicTexture2D t = new DX11DynamicTexture2D(context, this.FInW[0], this.FInH[0], SlimDX.DXGI.Format.B8G8R8A8_UNorm); | |
this.FTextureOutput[0][context] = t; | |
} | |
catch | |
{ | |
} | |
} | |
if (this.copyframe && this.FTextureOutput[0].Contains(context)) | |
{ | |
this.FTextureOutput[0][context].WriteData(this.rgbadata, this.size); | |
} | |
} | |
} | |
public void Destroy(IPluginIO pin, DX11RenderContext context, bool force) | |
{ | |
this.FTextureOutput[0].Dispose(context); | |
} | |
public void Dispose() | |
{ | |
this.FTextureOutput[0].Dispose(); | |
if (c != null) | |
{ | |
c.Close(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment