Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    GeClipMap and init(BaseBitmap)

    Cinema 4D SDK
    c++ sdk
    4
    13
    1.4k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • fwilleke80F
      fwilleke80
      last edited by

      Ah, learned something, too 🙂

      www.frankwilleke.de
      Only asking personal code questions here.

      1 Reply Last reply Reply Quote 0
      • WickedPW
        WickedP @ferdinand
        last edited by

        Thanks @ferdinand, that's really helpful. Your words explain what I see.

        I dug a little deeper, and since found my issue was bit-depth related. I've changed my Bitmap to 32bit now. That's fixed that part.

        However, it's introduced another issue. If I put any text in the clip map it shows up as a blank rectangle full of the set colour. The text only appears if I do something like draw a FillRect() underneath it first. Is this bit-depth related as well?

        Text without FillRect():
        42676991-9fb3-4797-9e52-e855836343cd-image.png

        Text with FillRect():
        317230fa-9931-42f1-9bf4-e7057f4e97fc-image.png

        [Note: just to put the two images above into context for you, the second one is like a 'mouse-over' effect of the first. But the text only reads in the second one, when the FillRect() is drawn 'underneath', or before, the call to TextAt().]

        WP.

        wickedp.com

        ferdinandF 1 Reply Last reply Reply Quote 0
        • ferdinandF
          ferdinand @WickedP
          last edited by

          Hey @wickedp,

          Yeah, that could be the case, there is some weird hacking going on in GeClipMap regarding the bit depth of the managed bitmap and I remember a comment warning about stuff being buggy or slow for the bit depth X (I do not recall the exact number).

          But I do not think that this is the case here, I assume you are using .TextAt() and drawing into an empty bitmap canvas. I recognized this before myself too: TextAt() seems to need pixels it can blend into, i.e., you cannot have text over a transparent background. When I stumbled upon this a while ago, I briefly play around with SetDrawMode with little luck and then simply assumed that you cannot have text over a transparent background. I did not dig any deeper then due to lack of time, so my assumption could have been false.

          It depends on what you want to do here. If this is just a question out of curiosity, I would leave it at this hint of mine. If you need text over a transparent background, I could have a deeper look, but I will probably only happen next week due to time restrictions and this probably being quite time consuming to find out (GeClipMap is itself only a frontend interface which operates on older and more low-level types).

          Cheers,
          Ferdinand

          MAXON SDK Specialist
          developers.maxon.net

          WickedPW 1 Reply Last reply Reply Quote 0
          • WickedPW
            WickedP @ferdinand
            last edited by

            Leave it with me @ferdinand, I'll dig a bit more tomorrow and over the weekend, and if no luck I'll get back to you (or I'll try a different drawing method).

            I'll let you know.

            WP.

            wickedp.com

            ferdinandF 1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand @WickedP
              last edited by

              Hello @wickedp,

              Okay, I will keep an eye on this thread.

              Cheers,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

              1 Reply Last reply Reply Quote 0
              • WickedPW
                WickedP
                last edited by

                OK, I had to jump through some hoops for one solution here.

                I created a separate GeClipMap, just the size of the text width and height. I added the text into this in a white colour. I then iterated over this text map and if the pixel was greater than black, I blended it in with the main clip map and the text colour needed. Not an ideal solution as it involves creating another temporary clip map, but they're only the size of the text so fairly small.

                While I'm on this one, is it safe to have two clip maps inside the BeginDraw() and EndDraw() functions at the same time?

                WP.

                wickedp.com

                ferdinandF 1 Reply Last reply Reply Quote 0
                • ferdinandF
                  ferdinand @WickedP
                  last edited by

                  Hey @wickedp,

                  great to hear that you found a solution and thank you for sharing your approach.

                  While I'm on this one, is it safe to have two clip maps inside the BeginDraw() and EndDraw() functions at the same time?

                  I am not quite sure how this is meant. Let's assume you have a BaseBitmap B and two GeClipMap instance CA and CB.

                  • Starting or stopping drawing operations for CA will have no impact on CB and vice versa.
                  • You can start and stop operations on CA and then start and stop then again on CA. This can for example be useful when you want to figure out which width and height a string S has before you define the size of a drawing canvas (so that S will fit into it). This also means that you can initialize the same canvas again.
                  • I would not recommend opening two canvases on the same bitmap source. As far as I know, a GeClipMap does not acquire a lock on its managed bitmap. So, when you then try to operate the two bitmaps without access boundaries as for example running them consecutively in a thread, you might run into crashes or garbage output when they both try to write the same data.

                  If this does not answer your question, I would ask for a clarification on what you mean, ideally with dummy code.

                  Cheers,
                  Ferdinand

                  MAXON SDK Specialist
                  developers.maxon.net

                  WickedPW 1 Reply Last reply Reply Quote 0
                  • WickedPW
                    WickedP @ferdinand
                    last edited by

                    @ferdinand said in GeClipMap and init(BaseBitmap):

                    Starting or stopping drawing operations for CA will have no impact on CB and vice versa

                    This might be the answer. But just to be sure...

                    The docs say that to use both Get/SetPixelRGBA() they have to be enclosed in BeginDraw/EndDraw(). So if we're handling two clip maps at the same time, for example reading from one and writing to another, can they both be 'active' between Begin/EndDraw() at the same time?

                    In my case, something like this:

                    /* pseudo code */
                    
                    GeClipMap *CA = GeClipMap::Alloc()...
                    // init CA etc. We'll draw text into this one
                    
                    GeClipMap *CB = GeClipMap::Alloc()...
                    CB->init(bmp); // init this one with another Bitmap
                    
                    CA->BeginDraw();
                    CB->BeginDraw();
                    
                    /* Add some text into our first clip map */
                    CA->SetColor(...);
                    CA->TextAt(...);
                    
                    /* 'for' loop here to iterate over CA, and copy into CB if colour from CA is not black */
                    LONG r,g,b,a;
                    for(int rows = 0; etc...)
                    {
                        for(int cols = 0; etc...)
                        {
                            /* Get rgba from CA */
                            CA->GetPixelRGBA(....);
                    
                            /* Check if red colour is greater than 0 */
                            if(r != 0)
                            {
                                /* Set/blend pixel colour into CB */
                                CB->SetRGBA(...);
                            }
                        }
                    }
                    
                    CA->EndDraw();
                    CB->EndDraw();
                    

                    In this case, we have to use GetPixelRGBA on the first clip map with the text, and are using SetPixelRGBA on the second clip map that's the BaseBitmap we're adding text into. They'd both be between Begin/EndDraw() at the same time in my example above. Is this OK?

                    For what it's worth, it seems to work in my plugin. But I want to check that it's safe to do.

                    WP.

                    wickedp.com

                    ferdinandF 1 Reply Last reply Reply Quote 0
                    • ferdinandF
                      ferdinand @WickedP
                      last edited by ferdinand

                      Hey @wickedp,

                      Generally speaking, I would say this is safe, but I am a bit reluctant to make such a broad statement. The specific code you have posted is however definitely safe.

                      As stated before, GeClipMap is just a front-end interface with a lower-level interface sitting behind it, let us call it Backend. Backend operates on the data managed by the GeClipMap, i.e., when you call Backend::DrawLine, you pass in a memory region, and it then does what it is told to do. Since each clipmap has its own managed memory unless you deliberately initialized it with the same memory, there will be no problems.

                      But there are methods like Backend::TextWidth or Backend::TextAt which then use OS resources. It seems unlikely that this will cause problems, but I cannot categorically deny it, as this then leaks into Windows, mac OS, and Linux OS code. I.e., two GeClipMap instances try to measure the width of a font from two threads at the same time. Something could go wrong there, depending on what the access restrictions of these OS resources are. But since we use GeClipMap also internally a lot, a Cinema 4D is drawing a lot of text, it seems very unlikely that there is any problem with that.

                      But your main concern seems to be if GeClipMap acts as a sort of singleton, i.e., that you can only have (or operate on) one instance at a time. That is not the case. You can have as many instances as you want. But when you open GeClipMap instances on the same memory, you can obviously run into problems, when you try to operate them in parallel. But that is not the case in your code, you are running everything consecutively, so both maps CA and CB could manage the same memory in this case.

                      Cheers,
                      Ferdinand

                      MAXON SDK Specialist
                      developers.maxon.net

                      1 Reply Last reply Reply Quote 0
                      • WickedPW
                        WickedP
                        last edited by

                        Sounds like what I'm doing should be OK then. If I run into any problems, I'll pop back in for further advice.

                        Thanks @ferdinand, your help is always appreciated. We can close this one.

                        WP.

                        wickedp.com

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post