3

I have a function that converting a RGB565 Texture2d to a RGB24Texture2d.

I use Texture2d.ReadPixs() api and it was successfully achieved but when it's running on android It will take 50 milliseconds on Texture2d.ReadPixs() and the readed size is just 640*480.

I find a solution here (to use glReadPixels) but when the so file was compiled from Android Studio it did not work on unity. I am not good at c++ and Android Studio...

Is there any other solution to fix it?

Thank you in advance!

 public static void textureToTexture2D(Texture texture, Texture2D texture2D)
 {
     if (texture == null)
         throw new ArgumentNullException("texture == null");
     if (texture2D == null)
         throw new ArgumentNullException("texture2D == null");
     if (texture.width != texture2D.width || texture.height != texture2D.height)
         throw new ArgumentException("texture and texture2D need to be the same size.");
     RenderTexture prevRT = RenderTexture.active;
     if (texture is RenderTexture)
     {
         RenderTexture.active = (RenderTexture)texture;
         
         texture2D.ReadPixels(new UnityEngine.Rect(0f, 0f, texture.width, texture.height), 0, 0, false);
         texture2D.Apply(false, false);
     }
     else
     {
         RenderTexture tempRT = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.ARGB32);
         Graphics.Blit(texture, tempRT);
         RenderTexture.active = tempRT;
        //it takes the most time on the function about 50ms
         texture2D.ReadPixels(new UnityEngine.Rect(0f, 0f, texture.width, texture.height), 0, 0, false);
         texture2D.Apply(false, false);
         RenderTexture.ReleaseTemporary(tempRT);
     }
     RenderTexture.active = prevRT;
 }
  • `Texture2D texture2d = (Texture2D) texture;` **DONE** ;). So... what are you trying to do here really? Copy pixels? Convert between formats? I'm confused. – Andrew Łukasik Jul 23 '20 at 08:10
  • Sorry about that . What I want is converting between formats(from rgb565 to rgb24). The process is Texture2d(rgb565)->Texture->RenderTexture->Texture2d(RGB24).ReadPixs() but ReadPixs Cost too muchtime. The useful way is to get data from rgb565 textur2d then reset data postion but this texture2d is created by Texture2d.CreateExternalTexture(),I cant get any data from Texture.GetPixs() or Texture.GetRawTextureData(). – Mizuhara Chizuru Jul 23 '20 at 11:09
  • That's unnecessarily complicated workflow to convert a small texture. Take a look at `texture.GetPixels()` method - it does most of the conversion work for you. – Andrew Łukasik Jul 24 '20 at 09:49

2 Answers2

1

You could also try using Graphics.CopyTexture

public Texture2D toTexture2D(RenderTexture rTex)
{
    Texture2D dest = new Texture2D(rTex.width, rTex.height, TextureFormat.RGBA32, false);

    Graphics.CopyTexture(renderTexture, dest);

    return dest;
}

Texture formats should be compatible (for example, TextureFormat.ARGB32 and RenderTextureFormat.ARGB32 are compatible).

You will need to check though if this is supported on your target device.

Some platforms might not have functionality of all sorts of texture copying (e.g. copy from a render texture into a regular texture). See CopyTextureSupport, and use SystemInfo.copyTextureSupport to check.

derHugo
  • 83,094
  • 9
  • 75
  • 115
1

Why not try something simple first:

Texture2D rgb565 = LoadMyTextureOrSomething();
Texture2D rgb24 = new Texture2D(
    width:          rgb565.width ,
    height:         rgb565.height ,
    textureFormat:  TextureFormat.RGB24 ,
    mipChain:       rgb565.mipmapCount!=1
);
rgb24.SetPixels( rgb565.GetPixels() );
rgb24.Apply();// sends changed texture to gpu

Some of this work can be done on worker thread (color conversion part), but requires manual byte[] or NativeArray<byte> processing (more on that here).

Andrew Łukasik
  • 1,454
  • 12
  • 19