Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Texture byte per pixel

Discussion in 'Scripting' started by AndersMalmgren, Feb 4, 2019.

  1. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    Hi,
    Is there a way to read the bytes per pixel from a texture?
    I'm trying to send a texture to a C API and it crashes the entire application

    Code (CSharp):
    1.             image.m_nBytesPerPixel = ???;
    2.             image.m_pImageData = MyImage.texture.GetNativeTexturePtr();
    3.             image.m_nWidth = MyImage.texture.width;
    4.             image.m_nHeight = MyImage.texture.height;
    Code (CSharp):
    1. typedef struct NotificationBitmap_t
    2. {
    3.     void * m_pImageData; // void *
    4.     int32_t m_nWidth;
    5.     int32_t m_nHeight;
    6.     int32_t m_nBytesPerPixel;
    7. } NotificationBitmap_t;
     
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    Both "Texture2D" and "RenderTexture" have a "format" property. The base class "Texture" does not.

    Here is a list of all TextureFormats, as well as how many bits they use: https://docs.unity3d.com/ScriptReference/TextureFormat.html

    I'm not sure if it will work, but I recommend trying this:
    Code (CSharp):
    1. switch (((Texture2D)MyImage.texture).format)
    2. {
    3.     case TextureFormat.Alpha8:
    4.         image.m_nBytesPerPixel = 1;
    5.         break;
    6.  
    7.     case TextureFormat.ARGB4444:
    8.         image.m_nBytesPerPixel = 2;
    9.         break;
    10.  
    11.     // ... implement other formats
    12. }
     
  3. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    wiill have a look. Thanks. I didn't get it to work with any byte per pixel though. Alps tried getting the byte buffer and getting the ptr to the array and use that, didn't work either
     
  4. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    Pretty sure the native library want a RGBA bitmap though since the name of the structure is NotificationBitmap_t
     
  5. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    I wonder if there is a problem with mono and pointers, I have gotten it to work with a vanilla .net project.

    There is a difference the pointers are hex in vanilla .net and decimal in mono,. dont know if its relevant.

    Mono
    upload_2019-2-5_10-30-32.png

    .net
    upload_2019-2-5_10-30-15.png
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,053
    I do this precise operation in my KurtMaster2D game, on Android, iOS, MacOSX and Windows.

    Here is my code to allocate and pin the texture, and pass the array of bytes into native code.

    Native code then renders to this buffer, and when it comes back I marshal back into a Texture2D for display.

    Code (csharp):
    1.  
    2.     public static void PinTextureAndCallNativeRenderColor( Texture2D t2d, int span, bool clean = false)
    3.     {
    4.         if (clean || (pixels == null) || (span != pixelSpan))
    5.         {
    6.             pixelSpan = span;
    7.             pixels = new Color32[ pixelSpan * pixelSpan];
    8.         }
    9.  
    10.         GCHandle handle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
    11.         try
    12.         {
    13.             dispatcher1_rendercolor( handle.AddrOfPinnedObject(), span, 0);
    14.         }
    15.         finally
    16.         {
    17.             if (handle.IsAllocated)
    18.             {
    19.                 handle.Free ();
    20.             }
    21.         }
    22.    
    23.         t2d.SetPixels32( pixels);
    24.         t2d.Apply();
    25.     }
    Here is the interop signature for that native method:

    Code (csharp):
    1.  
    2.     [DllImport ("__Internal")]
    3.     private static extern void dispatcher1_rendercolor(
    4.         System.IntPtr pixels, int span, int flags);
    And finally the actual native C code signature is (actually, here's the entire native C function):

    Code (csharp):
    1.  
    2. DECORATE_FOR_DLL    void    dispatcher1_rendercolor( void *rgbpixels, int span, int flags)
    3. {
    4.     if (wbi.workbuf_p)
    5.     {
    6.         int w = wbi.maxx;
    7.         int h = wbi.maxy;
    8.         unsigned char *ucptr = (unsigned char *)wbi.workbuf_p;
    9.         unsigned int *uptr = (unsigned int *)rgbpixels;
    10.         int    i, j;
    11.         for (j = 0; j < h; j++)
    12.         {
    13.             for (i = 0; i < w; i++)
    14.             {
    15.                 *uptr++ = kpios_last_palette_256_rgba[ *ucptr++];
    16.             }
    17.             uptr += (span - w);
    18.         }
    19.     }
    20.     else
    21.     {  // this simulates noise from a blank TV channel
    22.         int w = span;
    23.         int h = span;
    24.         int    i, j;
    25.         unsigned char *cptr = (unsigned char*)rgbpixels;
    26.         for (j = 0; j < h; j++)
    27.         {
    28.             for (i = 0; i < w; i++)
    29.             {
    30.                 *cptr++ = rand();
    31.                 *cptr++ = rand();
    32.                 *cptr++ = (rand() & 0xff) / 4;
    33.                 *cptr++ = 255;
    34.             }
    35.             cptr += 4 * (span - w);
    36.         }
    37.     }
    38. }
    NOTE: the "engines" inside this game collection are mostly 8-bit color, hence the palette expansion you see.

    NOTE: this same code runs on all targets: iOS 32bit, 64bit, Android 32bit, 64bit, MacOSX 64bit, and Windows 32-bit.

    And you can see it all in action here in the final product:

    Appstores:

    Apple iTunes: https://itunes.apple.com/us/app/kurtmaster2d/id1015692678

    Google Play: https://play.google.com/store/apps/details?id=com.plbm.plbm1
     
  7. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    Thanks. it seems to be a problem with the x64 dll. So Valve needs to fix that. It works with the x86 dll, but our game is x64 so need to use the x64 dll