Multiple texture-out for dynamic plugins

As title said, how can it be implemented more the one texture out inside a dynamic plugin ? (ca ben done right ? :)

should be possible. have you tried? where did you get stuck?

don’t know even how to declare/create the second pin, then observing the updateTexture function, I don’t know how to update separately 2 textures.

i think in that case you can’t use our base helper classes. you’ll have to write it on your own.

// class implementing VVVV.PluginInterfaces.V1.IPluginDXTexture2

[Output("Texture 1")](Output("Texture 1")) IDXTextureOut FTexture1Out;
[Output("Texture 2")](Output("Texture 2")) IDXTextureOut FTexture2Out;

void GetTexture (IDXTextureOut forPin, int onDeviceAddress, int slice, out int textureAddress)
{
  var devicePointer = new IntPtr(onDeviceAddess);
  // there is a method in slimdx to retrive the dx9device from an IntPtr.
  // at the end you must do something like
  // textureAddress = yourSlimDxTexture.ComPointer.ToInt32();
}

hope that gets you started. if you get stuck, look at the implementation of our base classes: http://vvvv.svn.sourceforge.net/viewvc/vvvv/AddonsCore/trunk/PluginInterfaces/V2/EX9/

thank u for pointing me there, that way can still be a dynamic plugin or is better to work on a compiled dll ?

My points :

  1. a dynamic dll can be easily modified by everyone and included in vvvv package

  2. i noticed the in openNISkeleton i developed, if i run it as compiled dll i have slower performance on building texture.
    If i use the same code in a dynamic plugin, the background texture loop doesn’t affect global performances, is it runs as precompiled DLL, I have to skip background rendering to achieve the dynamic code performance, still cant’ get what is depending by.

sure you can do it as dynamic plugin.

did you compile it in release configuration? by default an external ide compiles in debug configuration, that might be the cause for your performance loss.

for sure the debug configuration is about the loss of performance, still didn’t figure out how i can refere to 2 separated textures using my own class.

I started duplicatin the DXTexturePluginBase.cs, so it can handle mycustom needings, still i can’t get how to fill 2 different texture with 2 differents buffers, any help or pointing me somewhere ?

your device data would have two texture fields, vvvv calls the method:

void GetTexture (IDXTextureOut forPin, int onDeviceAddress, int slice, out int textureAddress)

in this method you have to return the right texture for this pin and slice, which you get out of your custom device data…

I’ve got this example from vux, got the point now :)

- region usings
using System;
using System.ComponentModel.Composition;
using System.Collections.Generic;

using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Utils.VMath;


using VVVV.Core.Logging;
using SlimDX;
using SlimDX.Direct3D9;

- endregion usings

namespace VVVV.Nodes
{
	#region PluginInfo
	[PluginInfo(Name = "Template", Category = "Multitexture", Help = "Basic template with one value in/out", Tags = "",AutoEvaluate=true)](PluginInfo(Name = "Template", Category = "Multitexture", Help = "Basic template with one value in/out", Tags = "",AutoEvaluate=true))
	#endregion PluginInfo
	public class MultitextureTemplateNode : IPluginEvaluate,IPluginDXTexture
	{
	
		IPluginHost FHost;
		
		#region fields & pins

		IDXTextureOut FTexOut1;

		IDXTextureOut FTexOut2;

        int w = 640;
        int h = 480;

       
		
		Dictionary<int,Texture> FTex1 = new Dictionary<int,Texture>();
		Dictionary<int,Texture> FTex2 = new Dictionary<int,Texture>();

		[ImportAttribute()](ImportAttribute())
		ILogger FLogger;
		
		[ImportingConstructor()](ImportingConstructor())
		public MultitextureTemplateNode(IPluginHost host)
		{
			this.FHost = host;
			
			this.FHost.CreateTextureOutput("Tex 1",TSliceMode.Single,TPinVisibility.True,out this.FTexOut1);
			this.FHost.CreateTextureOutput("Tex 2",TSliceMode.Single,TPinVisibility.True,out this.FTexOut2);
		}

		#endregion fields & pins
        
		//called when data for any output pin is requested
		public void Evaluate(int SpreadMax)
		{
			
		}
		
		public void GetTexture(IDXTextureOut ForPin, int OnDevice, out int tex)
		{	
			tex = 0;
			if (ForPin == this.FTexOut1)
			{
				if (this.FTex1.ContainsKey(OnDevice))
				{
	
					tex = this.FTex1[OnDevice](OnDevice).ComPointer.ToInt32();
				}
			}
			
			if (ForPin == this.FTexOut2)
			{
				if (this.FTex2.ContainsKey(OnDevice))
				{
					tex = this.FTex2[OnDevice](OnDevice).ComPointer.ToInt32();
				}		
			}
		}
		
		public void DestroyResource(IPluginOut ForPin, int OnDevice, bool OnlyUnManaged)
		{
			if (ForPin == this.FTexOut1)
			{
				FLogger.Log(LogType.Debug,"Bye Bye tex 1");
				if (this.FTex1.ContainsKey(OnDevice))
				{
					this.FTex1[OnDevice](OnDevice).Dispose();
					this.FTex1.Remove(OnDevice);
				}
			}
			
			if (ForPin == this.FTexOut2)
			{
				FLogger.Log(LogType.Debug,"Bye Bye tex 2");
				if (this.FTex2.ContainsKey(OnDevice))
				{
					this.FTex2[OnDevice](OnDevice).Dispose();
					this.FTex2.Remove(OnDevice);
				}		
			}
		}

		public void UpdateResource(IPluginOut ForPin, int OnDevice)
		{
			Device dev = Device.FromPointer(new IntPtr(OnDevice));

			if (ForPin == this.FTexOut1)
			{
                Texture t;
                if (!this.FTex1.ContainsKey(OnDevice) && bitmapPointer != IntPtr.Zero)
				{
                    t = new Texture(dev, w, h, 1, Usage.None, Format.A8R8G8B8, Pool.Managed);
                    this.FTex1.Add(OnDevice, t);

                    FLogger.Log(LogType.Debug, "Tex 1 Done");
					
				}
                t = this.FTex1[OnDevice](OnDevice);
                Surface srf = t.GetSurfaceLevel(0);
                DataRectangle rect = srf.LockRectangle(LockFlags.Discard);

                //// write data here 
                srf.UnlockRectangle();

			}
			
			if (ForPin == this.FTexOut2)
			{
                Texture t;
				if (!this.FTex2.ContainsKey(OnDevice))
				{
                    t = new Texture(dev, w, h, 1, Usage.None, Format.A8R8G8B8, Pool.Managed);
                    this.FTex2.Add(OnDevice, t);
                    FLogger.Log(LogType.Debug, "Tex 2 Done");
					
				}

                t = this.FTex2[OnDevice](OnDevice);
                Surface srf = t.GetSurfaceLevel(0);
                DataRectangle rect = srf.LockRectangle(LockFlags.Discard);

                //// write data here 
                srf.UnlockRectangle();
			}			
		}

        
	}
}

Bye Bye Tex1 :)

without that log message it doesnt work at all :D