Updating a texture live from a c++ plugin

I am trying to reproduce this technique:

http://forum.unity3d.com/threads/10682-Did-anyone-get-TexturePlugin-demo-to-work-on-Windows

But optimized with the use of SetPixels32, so that i dont have to send over all my RGBA in a float per channel format.

Here is what I am doing in my c++ plugin:

void EXPORT_API UpdateTexture( void* colors, int width, int height, float time )
{
	// safeguard - array must be not null
	if( !colors )
		return;
	
	// Color structure in Unity is four RGBA floats
	unsigned char* data = reinterpret_cast<unsigned char*>(colors);

	// Generate the texture data in funky ways
	// Or could just stream it from a webcam or however you like.
	for (int y=0;y<height;y++)
	{
		for (int x=0;x<width;x++)
		{
                     unsigned char* pixel = data + (y * width + x) * 4;
			// just a very simple scrolling sine waves pattern
                     pixel[0] = (unsigned char)((sinf( x * 0.13f + time * 2.1f ) * 0.5f + 0.5f) * 255.0f); // R
                     pixel[1] = (unsigned char)((sinf( y * 0.17f + time * 1.9f ) * 0.5f + 0.5f) * 255.0f); // G
                     pixel[2] = (unsigned char)((cosf( x * 0.21f + time * 2.3f ) * 0.5f + 0.5f) * 255.0f); // B
                     pixel[3] = 255; // A
		}
	}
}

and this is what I am doing in my C# script
public int width = 640;
public int height = 480;

protected Texture2D m_Texture;
protected Color32[] m_Pixels;
protected GCHandle m_PixelsHandle;


void setupImageUpdate()
{
    m_Texture = new Texture2D (width, height, TextureFormat.RGBA32, false);
    m_Pixels = m_Texture.GetPixels32 (0);
    m_PixelsHandle = GCHandle.Alloc(m_Pixels, GCHandleType.Pinned);

    m_ImagePlaneRenderer.material.mainTexture = m_Texture;
}

// Use this for initialization
void Start () 
{
	setupImageUpdate();
}

[DllImport ("UnityTexture")]
private static extern void UpdateTexture (IntPtr colors, int width, int height, float time);

// Update is called once per frame
void Update () 
{
    //UpdateTexture(m_PixelsHandle.AddrOfPinnedObject(), m_Texture.width, m_Texture.height, Time.time);
    m_Texture.SetPixels32(m_Pixels, 0);
    m_Texture.Apply(false,false);
}

I get an immediate crash (the unity gui crashes) when i try to run the system doing this. Anyone have a clue as to what I might be doing wrong? This works fine with the SetPixels method. Thanks for any help.

Buffer Locked before Copy?

I’m using a very similar setup and had some crashes initially. Turned out my crashes were because my pixel array was initially too small. I was resizing it later in my code, which is fine on the managed side with C#, but not a good thing to happen after pinning has already occurred. So I changed the code to make sure it was sized to what I knew I would need exactly, then the pinning shouldn’t be causing any later access violations.

That may not be your problem, but one thing I notice about your code that is very different from mine. You do not allocate separate memory for your pixel data from GetPixels32. It’s possible that you are simply getting access to the texture’s memory, and I’m not sure, but possibly that memory can’t be pinned. You wouldn’t see any problem in your code until you tried to access the memory from the unmanaged side.

I would try to allocate a separate array for your pixel data.

i.e.

Color32 rawPixels = new Color32[width * height];
m_PixelsHandle = GCHandle.Alloc(rawPixels, GCHandleType.Pinned);

Second, I’m using TextureFormat.ARGB32 not TextureFormat.RGBA32.

I’m also using Unity 5+ at this point, but do not think that should make any difference.
I hope this helps someone, since I know this is an old thread.