SOLVED HUD Text issues

Hi,

I am trying to display some text in the viewport. to do my tests I'm overriding the Draw method (objectdata plugin). Everything seems to work fine except two small things:

1- The text is not smooth : there is a slight aliasing on it.
2- The text is hidden under the bands that sourround the safe frame. for instance the default "Perspective" HUD text is visible even when you have 100% opaque bands.

    ...
    def Draw(self, op, drawpass, bd, bh):

        if drawpass == c4d.DRAWPASS_HIGHLIGHTS:
            return c4d.DRAWRESULT_SKIP

        bd.SetMatrix_Screen()
        bd.DrawHUDText(2, 25, "Perspective")

        return c4d.DRAWRESULT_OK

did I forget something? Any suggestion will be helpful.

Thanks !

a.png

It may surprise you, but I simply used DrawHUDText(). No low-level trickery, no touching the safe frames. I draw in SCENEHOOKDRAW::HIGHLIGHT_PASS.

Greetings,
Frank

Hello @kilou,

welcome to the forums and thank you for reaching out to us. Please make sure to read the Forum Guidlines, as your posting is missing critical information, which we require users to add in form of tags.

For your question:

  1. The BaseDarw.DrawHUDText method is very much different from the ones used internally by Cinema 4D. DrawHUDText does not support antialiasing. You can somewhat circumvent the problem by drawing a bitmap, but that approach comes with its own problems. See Draw HUD-like text to viewport for details.
  2. You cannot draw on top of safe frames inside NodeData.Draw, as this would defeat the purpose of safe frames. What you can do is draw in relation to the safe frame. See end of posting for details.

Cheers,
Ferdinand

    def Draw(self, op, drawpass, bd, bh):
        """Draws text into the passed BaseDraw.
        """
        # If the current draw pass is not the highlight draw pass, we skip 
        # this call. We cannot draw over the safe frames with any of the draw
        # passes as this would defeat the purpose of the safe frames of
        # blocking stuff out.
        if drawpass != c4d.DRAWPASS_HIGHLIGHTS:
            return c4d.DRAWRESULT_SKIP

        # Drawing in screen space does not take account of the safe frames
        # automatically, but we can get hold of them.
        bd.SetMatrix_Screen()

        # Get the frame of the safe frame.
        safeFrame = bd.GetSafeFrame()
        # The left and top offsets of the safe frame.
        cl, ct = safeFrame["cl"], safeFrame["ct"]

        # Draw at the point (5, 5) in the safe frame.
        bd.DrawHUDText(cl + 5, ct + 5, "Perspective")
        return c4d.DRAWRESULT_OK

First, thank you @ferdinand for your answer!

  • Q1: OK, thank you
  • Q2: this is exactly what I thought before until I saw a video of a plugin (Terraformx). The text was drawn on top of the safe frame (plase check out the image below).

terraform.png

.

  1. You cannot draw on top of safe frames inside NodeData.Draw....

By reading this part, should I understand that it's possible to achieve this by using a different plugin type (....a sceenhook plugin I guess) ? if so, how to do it ?

Thanks!

Hello @kilou,

@kilou said in HUD Text issues:

  • This is exactly what I thought before until I saw a video of a plugin (Terraformx). The text was drawn on top of the safe frame (please check out the image below).
    terraform.png
    By reading this part, should I understand that it's possible to achieve this by using a different plugin type (....a sceenhook plugin I guess)? if so, how to do it?

First of all, the SceneHookData plugin interface has not been wrapped for Python and is only available in C++. I have not yet tried myself when a SceneHookData is executed in the drawing pipeline. But since SceneHookData is derived from NodeData, i.e., the same type ObjectData and TagData are derived from, I would doubt that its Draw method is treated much differently. I.e., I would assume it to be also drawn before the safe frames.

There are effectively two ways how I could see how Frank has done this:

  1. He used either one of the more low-level access public maxon API viewport drawing access points or the non-public viewport API. Both are not accessible in Python and the latter is deliberately not public and we cannot change this for now.
  2. Possible could be also, that he simply cheated, like I have shown it here. The idea is to turn of the build in safe frames and draw your own, enabling you to do pretty much whatever you want. The problem with this is for once performance, but also the fact that you have to make sure yourself that the safe frames are drawn above everything else.

Cheers,
Ferdinand

PS: The author of Terraform is @fwilleke80, the author of the topic Draw HUD-like text to viewport I did reference above. For details on how he did accomplish exactly what he did, you could try to ask him.

It may surprise you, but I simply used DrawHUDText(). No low-level trickery, no touching the safe frames. I draw in SCENEHOOKDRAW::HIGHLIGHT_PASS.

Greetings,
Frank

Thank you @ferdinand! I appreciate the effort you put in your answers. very detailed and clear. Thank you again.

Thank you @fwilleke80 for your answer!
honestly, to be surprised, I'm surprised! seeing the video, I was pretty sure that DrawHUDText() method was used, but how did you manage to get this result ? (smooth text, visible above the safe frame!).. because when I used it, it was ...meh!

Best regards,

If I remember correctly, I decided to just not spend any more time on this issue, and rather keep the number of HUD elements low to avoid speed issues. Why the rest just works, I don’t know. Maybe it’s just the right drawpass for it.

Hello @fwilleke80,

thank you for jumping in and offering help. Good to know that SceneHookData can draw on top of everything, which makes sense, given the nature of scene hooks. For clarification for @kilou: The draw pass flags in SCENEHOOKDRAW are not available in in other implementations of Draw (ObjectData, TagData, ect.) and therefore not available in Python due to its lack of SceneHookData. If you are hellbent on doing it, I would recommend 'faking' it as lined out in my previous posting.

Cheers,
Ferdinand

Oh! sorry @fwilleke80 I misread your first message.

@ferdinand, I think I got confused from the beginning. I made a copy of my code from an objectData plugin to a scenehook plugin without changing DRAWPASS to SCENEHOOKDRAW 🤦

Everything is working just fine now(... except the aliasing) but the result is acceptable.

OK.png

Thanks to both of you!
Best Regards,