fedegen
Topic Author
Posts: 6
Joined: 30 Sep 2015, 22:25

[Unity] get Texture2D from textureSource?

01 Dec 2015, 15:35

Hi !
Using the sample from imagestutorial i could convert a texture2D to texturesource:
Grid grid = GetComponent<NoesisGUIPanel>().GetRoot<Grid>();

Texture2D texture = Resources.Load("Noesis") as Texture2D;
TextureSource source = new TextureSource(texture);

Image image = grid.FindName<Image>("image");
image.SetSource(source);
Now, I need to get the texture2d from the TextureSource.
Something like this:

bMyLogo.GetBackground().As<ImageBrush>().GetImageSource().As<TextureSource>().GetTexture2D()

Is there any way to do this?

Thanks in advance.
 
User avatar
jsantos
Site Admin
Posts: 2906
Joined: 20 Jan 2012, 17:18
Contact:

Re: [Unity] get Texture2D from textureSource?

01 Dec 2015, 20:08

Right now, it cannot be done. We could expose the internal texture handle used by TextureSource as IntPtr and use that handle to create an external texture in Unity.

It is a problematic path, because the internal handle could be invalid until the render thread really creates the GPU texture.

Could you please elaborate more about why you need it?
 
fedegen
Topic Author
Posts: 6
Joined: 30 Sep 2015, 22:25

Re: [Unity] get Texture2D from textureSource?

02 Dec 2015, 14:25

Hi again, and thanks for your answer.
I need the Texture2d because I let the user to make his own logo, and then i use it in some sprites.

1)Load logos from ResourceDictionary.
2)The user choose one, and customize it (color, size..).
3)Then i want to get the Texture2d from the customized logo to use it as a texture for some sprites.

But it' ok.
When i read your answer i try another way and i could get the Texture2d using ReadPixels() from the screen.

The only problem i got now is if i run ReadPixels like Unity recommends (in a coroutine after a WaitForEndOfFrame) the captured image is black.
But if i run ReadPixels inside a common method(buttonClick), Unity throw an exception (i ignore it) and the captured image is fine.

Maybe you have an idea of how can i run ReadPixels inside the coroutine to avoid the Unity exception?

This is my coRoutine to capture the image in a Texture2D returning a black image(the parameter is a Unity.Rect with the points and size of the UIElement with the image i want to capture):
private IEnumerator coRoutineCaptureScreenZone(Rect rect)
    {
        Texture2D tex = new Texture2D(Convert.ToInt32(rect.width), Convert.ToInt32(rect.height), TextureFormat.ARGB32, false);
        // Read screen contents into the texture
        yield return new WaitForEndOfFrame();

        // Read screen contents into the texture
        tex.ReadPixels(rect, 0, 0);
        tex.Apply();

        yield return tex;
    }
And this is the code to run ReadPixels inside a common method like buttonClick (it's works but Unity throw this exception "ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame."):
                float width = bMyLogo.GetActualWidth();
                float height = bMyLogo.GetActualHeight();
                Point pos = bMyLogo.PointToScreen(Point.Zero());

                Texture2D companyLogo = new Texture2D(Convert.ToInt32(width), Convert.ToInt32(height), TextureFormat.ARGB32, false);

                companyLogo.ReadPixels(new UnityEngine.Rect(pos.x, pos.y, width, height), 0, 0);
                companyLogo.Apply();
 
User avatar
jsantos
Site Admin
Posts: 2906
Joined: 20 Jan 2012, 17:18
Contact:

Re: [Unity] get Texture2D from textureSource?

02 Dec 2015, 23:19

Not sure about those errors with ReadPixels because I never tried it, if nobody can help you with that here I recommend going to Unity forums.

Anyway, if performance is important ReadPixels() is not the best option. I think that rendering the UI to a RenderTexture is the best way.
 
fedegen
Topic Author
Posts: 6
Joined: 30 Sep 2015, 22:25

Re: [Unity] get Texture2D from textureSource?

03 Dec 2015, 16:39

I checked the Unity Forum looking for the error, and always solve it calling WaitForEndOfFrame() before ReadPixels().
http://forum.unity3d.com/threads/textur ... ne.155194/
http://answers.unity3d.com/questions/32 ... drawi.html

If i try my code in an Unity Project without NoesisGui it works fine (the captured image is not black).

I guess is something related to WHEN NoesisGui is rendered. Maybe when WaitForEndOfFrame is called, the NoesisGUI is not rendered yet?

I checked your advice of using RenderTexture too, but i need to call ReadPixels() anyway. Or there is another way?
RenderTexture.active = myRenderTexture;
 myTexture2D.ReadPixels(new Rect(0, 0, myRenderTexture.width, myRenderTexture.height), 0, 0);
 myTexture2D.Apply();
Anyway, calling ReadPixels() in a buttonclick method and ignoring the Unity Error is working fine for now.
But if someone knows a better way of doing this, please let me know.

Thanks for your time, jsantos.
 
User avatar
jsantos
Site Admin
Posts: 2906
Joined: 20 Jan 2012, 17:18
Contact:

Re: [Unity] get Texture2D from textureSource?

04 Dec 2015, 13:55

We are also waiting using WaitForEndOfFrame() for rendering the UI. That would explain the problem you are having.

If you follow the RenderTexture way, you don't need to copy using ReadPixels() because RenderTexture is also (inherits) a Texture so you could use that same object, couldn't you?
 
fedegen
Topic Author
Posts: 6
Joined: 30 Sep 2015, 22:25

Re: [Unity] get Texture2D from textureSource?

04 Dec 2015, 18:03

I am not sure, i guess i need a Texture2d anyway.

Like i said before, I need to use the texture in a sprite, so i am using:
Sprite.Create(customTexture, .....
to do this.

And Sprite.Create need a Texture2d, not a RenderTexture. That's why i guess i must get the texture2d using ReadPixels().
 
User avatar
jsantos
Site Admin
Posts: 2906
Joined: 20 Jan 2012, 17:18
Contact:

Re: [Unity] get Texture2D from textureSource?

04 Dec 2015, 20:10

You are true, RenderTexture inherits from Texture not Texture2D

http://answers.unity3d.com/questions/99 ... ure2d.html

But may be using this way you don't get error in ReadPixels. I don't understand why you are having that error.
 
fedegen
Topic Author
Posts: 6
Joined: 30 Sep 2015, 22:25

Re: [Unity] get Texture2D from textureSource?

09 Dec 2015, 17:02

Hi jsantos, sorry for the late answer.

Same error. The only way i've found to run ReadPixels() without this error is in an coRoutine after WaitForEndOfFrame().
I can't explain why... I guess only Unity people knows. In older versions of Unity (before 4)this error doesn't happens. And the capture works fine catching the exception and ignoring it. Is really weird...

Anyway, the error becomes a problem because NoesisGui uses WaitForEndOfFrame() too like you said before.
Is there some event in NoesisGui to know when it finish rendered itself to try call it before ReadPixels() replacing WaitForEndOfFrame()? Maybe this avoid the Unity error...
 
User avatar
jsantos
Site Admin
Posts: 2906
Joined: 20 Jan 2012, 17:18
Contact:

Re: [Unity] get Texture2D from textureSource?

09 Dec 2015, 18:55

Our render code is (Assets\Plugins\NoesisGUI\Scripts\NoesisGUIPanel.cs):
IEnumerator RenderAtEndOfFrame()
{
    yield return waitEndOfFrame;
    _uiRenderer.PostRender();
}
Could you insert your code after the PostRender() function just to verify if that way you don't get errors?

Who is online

Users browsing this forum: Google [Bot] and 1 guest