problem with accessing color values of Color32 in C plugin

Hello,

My short question is this: What is the packing of Color32 unity classes? I have been led to believe through the access violation errors in my c plugins, which write to pointer to Color32, that the packing is NOT 8888 for RGBA or 32 bbp as it is for the Color class.

Long winded question, I have written a plugin to write color values to unity textures. My first iteration of the program used Color to store color values with unity. My C# unity side the program was taken from the texture plug sample located here : http://unity3d.com/support/resources/example-projects/texture-plugins. The relevant code snippet for creating and sending the texture pointer is:

using UnityEngine;
using System;
using System.Runtime.InteropServices;

public class TexturePlayback : MonoBehaviour {

public int width = 256;
public int height = 256;
private Texture2D m_Texture;

private Color[] m_Pixels;
private GCHandle m_PixelsHandle;
    
void Start () {
    // Create texture that will be updated in the plugin
    m_Texture = new Texture2D (width, height, TextureFormat.ARGB32, false);
    // Create the pixel array for the plugin to write into at startup    
    m_Pixels = m_Texture.GetPixels (0);
    // "pin" the array in memory, so we can pass direct pointer to it's data to the plugin,
    // without costly marshaling of array of structures.
    m_PixelsHandle = GCHandle.Alloc(m_Pixels, GCHandleType.Pinned);

    // Assign texture to the renderer
    if (renderer)
        renderer.material.mainTexture = m_Texture;
    // or gui texture
    else if (GetComponent(typeof(GUITexture)))
    {
        GUITexture gui = GetComponent(typeof(GUITexture)) as GUITexture;
        gui.texture = m_Texture;
    }
    else
    {
        Debug.Log("Game object has no renderer or gui texture to assign the generated texture to!");
    }
}

void OnDisable() {
    // Free the pinned array handle.
    m_PixelsHandle.Free();
}

// Link to the UnityTexture plugin and call the UpdateTexture function there.
[DllImport ("UnityTexture")]
private static extern void UpdateTexture (IntPtr colors, int width, int height, float time);

// Now we can simply call UpdateTexture which gets routed directly into the plugin
void Update () {
    UpdateTexture (m_PixelsHandle.AddrOfPinnedObject(), m_Texture.width, m_Texture.height, Time.time);
    m_Texture.SetPixels (m_Pixels, 0);
    m_Texture.Apply ();
}

}

The relevant C plugin code for the UpdateTexture function is:


float* data = reinterpret_cast<float*>(destination); // destination is texture pointer “m_PixelsHandle.AddrOfPinnedObject()” from unity

for(int y=0; y < height; y++){
	for(int x=0; x < width; x++){
		float* pixel = data + (y * width * 4 + x * 4);
		pixel[0] = 1.0f; 
		pixel[1] = 0.0f;
		pixel[2] = 0.0f;
		pixel[3] = 1.0f;
	}
}

Everything is going swimmingly when I use Color class and the texture is correctly changed to red. However, SetPixel is rather slow for large textures and I heard SetPixel32 is faster. So I changed the C# code to Color32 and SetPixel32, from Color and SetPixel respectively. However, this now causes an access violation on my plugin, thus leading me to believe the color data for Color32 is packed differently than Color. Is this the case? And if so, how are the color values stored in the Color32 class? If this is not the case and the program is failing for another unforeseen reason, I would appreciate any kind words of enlightenment.

thank you

Per NOAA_Julien’s suggestion, the Color32 structure is indeed packed as bytes rather than floats. Unity - Scripting API: Color32 So a little change to my above plug-in code to represent the texture array from unity as unsigned chars fixed the problem:

    ...
    unsigned char* data = reinterpret_cast<unsigned char*>(destination); 
    for(int y=0; y < height; y++){
       for(int x=0; x < width; x++){
	      unsigned char* pixel = data + (y * width * 4 + x * 4);
	      pixel[0] = (unsigned char) 255; //RED
	      pixel[1] = (unsigned char) 0; 
	      pixel[2] = (unsigned char) 0;
	      pixel[3] = (unsigned char) 255;
       }
    }
    ...

Also, for those interested, the change from SetPixels to SetPixels32 is an increase of about 33% in frame rate on SD sized textures.