Author Topic: Texture or material changes in UITexture does not propagate to _UIDrawCall  (Read 36910 times)

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Ok, I've been banging my head against a wall these past two days and I think I have an NGUI bug on my hands.

I have a scrollpanel with elements in, these include a friend picture in a UITexture (downloaded from online).

These UITextures should be able to update while being on the screen.

To test it out, I've made a little changepic script like so:

  1. int num = 0;
  2.         void OnClick()
  3.         {
  4.                 if (num % 2 == 0)
  5.                 {
  6.                         friendPicture.mainTexture = dummyFriendImage;
  7.                         //friendPicture.panel.MarkMaterialAsChanged(friendPicture.material, true); //did nothing
  8.                         //friendPicture.panel.UpdateDrawcalls(); //did nothing
  9.                        
  10.                 }
  11.                 else
  12.                 {
  13.                         friendPicture.mainTexture = dummyImage;                                
  14.                 }
  15.                 Debug.Log("num " + num);
  16.                 num++;
  17.         }
  18.  

where dummyImage and dummyFriendImage are set to something different in the inspector, of course.


So, my UIpanel has AlphaClipping and I set the UITexture to use the same shader ("unlit/Transparent Colored (AlphaClip)") otherwise it won't clip properly with the default ("unlit/texture").

If the picture is on screen, the change happens in the texture in the inspector just fine, but nothing happens on screen. When I set the panel's Debug Info to "Geometry" and look at the _UIDrawCall for the respective picture, it sill points to the old picture that was set on start up.

If I scroll the picture out of the clip rect, it gets removed and when I scroll it back in, it makes a new one with the new picture. It never changes if it stays on screen.

Is there a way I can force it to update?

I've tried MarkAsChanged on the UITexture and the ones you see in the code above, but none of the do anything. I've half a mind to take all the UIpanel's drawcalls and destroy them, so it can rebuild, but I fear it will backfire on me and either give a frame of blank space or just explode.

Help me ArenMook Kenobi, you're my only hope.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #1 on: December 05, 2012, 10:55:18 AM »
Ok, so.. a fix:
  1. friendPicture.mainTexture = dummyImage;
  2. friendPicture.panel.depthPass = true;
  3. StartCoroutine(DisableDepthPass());
  4.  

  1. IEnumerator DisableDepthPass()
  2.         {
  3.                 yield return null;
  4.                 friendPicture.panel.depthPass = false;
  5.         }

But it's a damn ugly hack. :)

Agamemjohn

  • Guest
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #2 on: December 05, 2012, 03:16:13 PM »
I'm seeing this problem as well. I worked around it for the moment by simply not updating the textures after the first mainTexture set in UITexture.

I'd really like to do some dynamic loading like Nicki describes, but it looks like the materials on the draw calls aren't being updated.

In my case, I'm dynamically generating textures and applying them at runtime, and times I need to refresh these textures. So I destroy the old textures (in order to not leak memory), and when I apply my new textures to the UITexture, it applies as expected, but the draw call loses its texture when the Destroy call happens on the old texture.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #3 on: December 05, 2012, 06:27:38 PM »
When setting the UITexture's mainTexture value, make make sure that you don't have an explicit material defined on it. Ie: if you created a material called "My Material" and assigned it to UITexture, changing the mainTexture property will change the material's texture, which may or may not be what you want. If you don't specify a material, then I'd expect it to work properly. Is that not what you're seeing?

The depth pass seems highly odd to me. All you're doing is switching the shader for one frame.

Agamemjohn

  • Guest
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #4 on: December 05, 2012, 06:37:29 PM »
I'm not setting a material, I thought the same thing you did, and after looking at the UITexture code, I made sure to let the UITexture manage the materials.

And I investigated Nicki's solution too, and I think that the reason it works for him is that it eventually gets propagated down to the DrawCall, which sets the mReset flag to true, which looks like it forces an update of the Materials. Definitely not pretty.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #5 on: December 06, 2012, 03:03:47 AM »
I was desperate, and it solved it. :P

I've tried both with setting my own material and setting only mainTexture and either of them don't get refreshed while being on screen.

Even if I have it in the editor and I pull a new texture onto the UITexture's Texture slot, it doesn't update in the _UIDrawCall.

My guess is too that depthPass changes all the drawcalls and thus remakes the whole thing, rebuilding from the sources.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #6 on: December 06, 2012, 05:32:01 AM »
A simple repro case would be nice :P (sent to support at tasharen.com)

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #7 on: December 06, 2012, 01:30:54 PM »
We have some deadline stuff tomorrow, but I'll make you one next week or maybe during the weekend if I'm bored. ;)

Agamemjohn

  • Guest
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #8 on: December 06, 2012, 01:42:52 PM »
We've got some pretty high-priority stuff to work on now too, that I've worked around the issue.

I'll try to put something together today or tomorrow, though.

ryan

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 90
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #9 on: December 06, 2012, 02:52:42 PM »
I don't know if this is bad practice, but I usually end up setting my UITexture's .material to a copy of the original, then any time I need to change the texture, I set .material.mainTexture instead of .mainTexture.  This may just be a holdover from earlier versions of NGUI where the UITextures needed explicit materials to be set.  A lot of the places where I use UITexture, I'm instantiating a prefab multiple times, and not copying the material meant updating one UITexture affected all of them.

Anyway, for Nicki's original problem, just wondering if setting friendPicture.material.mainTexture would be an easy solution.

Agamemjohn

  • Guest
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #10 on: December 06, 2012, 04:59:27 PM »
Interestingly enough ryan, my original solution was to do just that. It wasn't working in certain cases (usually when there was a UITable that had clipping enabled, but I'm not confident yet that was the sole reason).

And when I say wasn't working, I mean the UITexture's referenced material had the correctly assigned textures (especially since I manually assigned them in a case similar to yours), and in another where I let the UITexture manage that material. But the material that the _DrawCall_ was using had a null texture assigned. I presume that the DrawCalls use dynamically generated materials (especially when enabling clipping). That texture was the one that was invalid. So all the data that was obviously examinable by me looked great, but if I went to the offending panel, then turned on "show geometry" debug mode, I can examine the draw call GameObject and see the missing texture. If I force a refresh of the UIPanel generating that DrawCall (disable, then enable the component), everything looks correct.

Agamemjohn

  • Guest
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #11 on: December 06, 2012, 06:11:22 PM »
So, thanks for talking it out with us, Aren and ryan. It looks like the swap to a clipped shader is the culprit.

I'm packaging up a repro case now, Aren, and I'll get it sent off to you (still gotta remove unneeded resources to simplify it).

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #12 on: December 08, 2012, 04:10:15 PM »
Ryan: Nah, that doesn't work. I've tried that as well.

I'm pretty sure it has something to do with the shader as well, but I dunno. I've sent a repro case to ArenMook, so hopefully he can figure it out. :)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #13 on: December 08, 2012, 11:25:11 PM »
Yup, I received it though haven't had a chance to look at it yet. TNet took up my Saturday.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Texture or material changes in UITexture does not propagate to _UIDrawCall
« Reply #14 on: December 09, 2012, 02:29:35 PM »
I've tracked down and fixed the issue. You will see it working properly in 2.2.7 (or if you have Pro you can grab it and test it now).