Adam's Lair Forum

game development and casual madness
It is currently 2018/04/25, 06:57

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 12 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: 2013/07/22, 14:20 
Member
Member

Joined: 2013/05/20, 17:19
Posts: 77
Role: Professional
I may just be having a slow morning but I can't seem to get screen overlay rendering to work anymore, and looking at the code in Camera.CollectDrawCalls, it looks like renderers with the ScreenOverlay visibility group will never be rendered. They're being masked out. Did this change at some point, because I'm sure I had it working before.

Also, awesome news that you've moved to GitHub for hosting. I'm sure you won't regret it, and it'll definitely make life easier for us:)


Top
 Profile  
 
PostPosted: 2013/07/22, 15:47 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2042
Location: Germany
Role: Professional
I haven't changed anything related to Screen Overlay rendering lately and I'm doing it successfully right now, in another project of mine - so my best guess is that slow morning theory :D

This might help:
Code:
public class SomeScreenOverlayRenderer : Component, ICmpRenderer
{
   float ICmpRenderer.BoundRadius
   {
      get { return float.MaxValue; }
   }
   bool ICmpRenderer.IsVisible(IDrawDevice device)
   {
      return
         // Make sure the ScreenOverlay flag is set
         (device.VisibilityMask & VisibilityFlag.ScreenOverlay) != VisibilityFlag.None &&
         // Make sure some other flag is also set.
         (device.VisibilityMask & ~VisibilityFlag.ScreenOverlay) != VisibilityFlag.None;
   }
   void ICmpRenderer.Draw(IDrawDevice device)
   {
      Canvas canvas = new Canvas(device);
      canvas.DrawText("Hey! I'm rendered as a Screen Overlay!", 10, 10);
   }
}


It's a minimal Screen Overlay renderer implementation. If it doesn't work, another error source is your Camera RenderPass config. By default, there is one pass for Screen Overlays, but it is entirely possible to remove that pass - if you or someone else happened to do so, no Screen Overlay will be rendered at all.

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
PostPosted: 2013/07/22, 16:12 
Member
Member

Joined: 2013/05/20, 17:19
Posts: 77
Role: Professional
Thanks Adam. I'm actually just trying to get a TextRenderer to draw in ScreenOverlay mode, so I don't think I need a custom renderer. I just have the TextRenderer component's VisibilityGroup set to AllFlags. The last pass of our rendering pipeline is definitely ScreenOverlay, so that's not it.

This works in the scene editor, but not in game view, and I can see that the CamViewState class does some extra stuff to collect draw calls, so I'm wondering if that's why it works in the editor? Do I actually have to attach a handler to the CollectDrawcalls method and do my own collecting of renderers every frame, for ScreenOverlay stuff? Does this line from the Camera class

Code:
// If no visibility groups are met, don't bother looking for renderers
if ((this.drawDevice.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None) return;


basically say that unless I do my own collecting of renderers, ScreenOverlay stuff will never be drawn?

We also have a lot of post-processing going on in our camera passes. I can't see any reason that that would have anything to do with this problem, but maybe you've got some nuggets of wisdom about that approach?


Top
 Profile  
 
PostPosted: 2013/07/22, 16:37 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2042
Location: Germany
Role: Professional
BraveSirAndrew wrote:
Do I actually have to attach a handler to the CollectDrawcalls method and do my own collecting of renderers every frame, for ScreenOverlay stuff? Does this line from the Camera class

Code:
// If no visibility groups are met, don't bother looking for renderers
if ((this.drawDevice.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None) return;


basically say that unless I do my own collecting of renderers, ScreenOverlay stuff will never be drawn?


No. The only purpose of that line is to omit RenderPasses that would mask out everything i.e. draw nothing. There is no reason you would need to attach a drawcall collector event handler and without a very good reason, you shouldn't use that one anyway. :) In other words: I see no reason why your TextRenderer shouldn't work. In fact, I've just tried it out in a fresh Duality version:

  1. Create a new Camera and position it at 0,0,-500
  2. Create a new SpriteRenderer and position it at 0,0,0 for reference
  3. Create a new TextRenderer and position it at 200,200,0
  4. Set the TextRenderers VisibilityGroup to "All" or simply add the "ScreenOverlay" flag

And it works. Can you verify that?
  1. Using a fresh Duality installation from the official download?
  2. Using a fresh custom built Duality installation using your branched code?
  3. Using a new Scene inside your existing project?
  4. Using a new Camera inside the existing Scene where the problem occurs?
  5. Using the problematic Camera but with its RenderPasses reset?

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
PostPosted: 2013/07/22, 16:45 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2042
Location: Germany
Role: Professional
Quick guess to try out first: Check the VisibilityMask property of the RenderPass that does your ScreenOverlay rendering. In the default version, it is set to "All" and it probably should be in your case as well. The flag "ScreenOverlay" alone is not a valid visibility group - it's a flag extending another group, so setting "ScreenOverlay" without any other flag set won't work.

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
PostPosted: 2013/07/22, 17:13 
Member
Member

Joined: 2013/05/20, 17:19
Posts: 77
Role: Professional
Ah, that was it, but I don't fully understand the logic.

If I set the last RenderPass of my camera to render ScreenOverlay plus Group0 for example, it doesn't really render anything from Group0, only renderers that have a VisGroup of ScreenOverlay? So is the group slightly redundant? Is it there only to make sure the masking logic works?


Top
 Profile  
 
PostPosted: 2013/07/22, 17:29 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2042
Location: Germany
Role: Professional
You apparently found a bug, because clearly the logic as it is supposed to be differs from the one that is currently implemented. I'll fix it in the upcoming source update. :)

Behavior as intended to be:

  • If ScreenOverlay is not set, render everything that does not match the ScreenOverlay flag and matches at least one other VisibilityFlag.
  • If ScreenOverlay is set, render everything that matches both ScreenOverlay and at least one other VisibilityFlag.

Behavior as it turned out to be after I've tested it right now:

  • If ScreenOverlay is not set, render everything that does not match the ScreenOverlay flag and matches at least one other VisibilityFlag.
  • If ScreenOverlay is set, render everything that matches at least ScreenOverlay itself.

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
PostPosted: 2013/07/22, 17:44 
Member
Member

Joined: 2013/05/20, 17:19
Posts: 77
Role: Professional
Awesome:)


Top
 Profile  
 
PostPosted: 2017/07/22, 13:39 
Junior Member
Junior Member

Joined: 2017/07/20, 18:17
Posts: 27
Location: Germany
Role: Hobbyist
I am currenlty looking into UI with Duality and found some strange behavior while deactivating the screen overlay. I have to ressurect this thread, because the unintended behaviour described first still occurs:
Adam wrote:
Behavior as it turned out to be after I've tested it right now:

  • If ScreenOverlay is not set, render everything that does not match the ScreenOverlay flag and matches at least one other VisibilityFlag.
  • If ScreenOverlay is set, render everything that matches at least ScreenOverlay itself.

I made a simple scene with two game objects: A Camera and a sprite using SpriteRenderer with VisbilityGroup = Group0. If the ScreenOverlay flag is removed from the VisibilityMask of the camera, the sprite can be seen two times, one time for normal rendering in its world position and one time for the UI rendering in its UI position. I assume the cause is the first line in IsVisible of the SpriteRenderer, it will be "0 != 0" in the described case and will then not return false, instead it depends on the IsCordInView-Call:
Code:
/// <summary>
/// Determines if the Renderer is visible to the specified <see cref="IDrawDevice"/>.
/// This is usually the case if they share at least one mutual <see cref="VisibilityGroup">visibility group</see>.
/// </summary>
/// <param name="device"></param>
/// <returns></returns>
public virtual bool IsVisible(IDrawDevice device)
{
    if ((device.VisibilityMask & VisibilityFlag.ScreenOverlay) != (this.visibilityGroup & VisibilityFlag.ScreenOverlay)) return false;
    if ((this.visibilityGroup & device.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None) return false;
    return device.IsCoordInView(this.gameobj.Transform.Pos, this.BoundRadius);
}

Here also two screenshots to demonstrate:
https://picload.org/view/rpwprgra/camer ... k.jpg.html
https://picload.org/view/rpwprgrl/camer ... s.jpg.html

The behavior may be intended in the current version, but then I need some explanation to understand.


Top
 Profile  
 
PostPosted: 2017/07/22, 22:21 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2042
Location: Germany
Role: Professional
Hey there,

not sure whether the behavior you're observing right now is exactly the same as was discussed before in this thread, but in general there are technical reasons for this ScreenOverlay behaving differently - mostly because it's a special flag that is not really intended to be changed away from the default in a visibility mask. Still, due to the mismatch between user expectations and actual behavior, this can also be classified as a bug, with potential fixes ranging from prohibiting changing the property in that case, to implementing an internal workaround / special case.

For further discussion and to make sure this won't escape again, can you file an issue on GitHub mirroring your description of the issue?

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group