VideoPostData plugin Render Region not working



  • On 09/10/2014 at 06:34, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   15 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hi Plugincafe,

    I'm writing a VideoPostData plugin. In this example I simply write all white to the RGBA buffer and call SkipRenderProcess(). Everything works fine for Editor Viewport, Picture Viewer and even Active Render Region. The "Render Region" although seems to hand wrong parameters to my plugin, the dimensions are the one for the whole Editor Viewport instead of the render region. So the result is that the whole Editor Viewport is white instead of only the selected region. Here is an image which should make it clear. The Code is given below.

    RENDERRESULT MyVideoPostPlugin::Execute(BaseVideoPost* node, VideoPostStruct* vps)
    {
        if (vps->error == nullptr || *vps->error != RENDERRESULT_OK || vps->thread->TestBreak())
        {
    // After skipping the render process vps->error is set, so we end up here and return
            return RENDERRESULT_OK;
        }

    if (vps->vp == VIDEOPOSTCALL_INNER && vps->open)
        {
            BaseObject* pBaseObject = (BaseObject* )node;
            BaseContainer* pBaseContainer = pBaseObject->GetDataInstance();

    VPBuffer\* pVpBuffer = vps->render->GetBuffer(VPBUFFER_RGBA, 0);
    
    
    // fill pVpBuffer with custom render data, in my example just white
    

    vps->vd->SkipRenderProcess();
    return RENDERRESULT::RENDERRESULT_USERBREAK;
        }

    return RENDERRESULT_OK;
    }



  • On 09/10/2014 at 09:01, xxxxxxxx wrote:

    The problem is almost certainly coming from your code that draws the white lines using the buffer.
    But you didn't post the code that you're using to draw that.

    -ScottA



  • On 09/10/2014 at 11:19, xxxxxxxx wrote:

    You probalby will need to extract the exact region yourself and only draw then. You should be able to retrieve the region x/y coordinates from the vps->render->GetRenderData() container. Check out the docs of RenderData to see the container ids.



  • On 09/10/2014 at 12:10, xxxxxxxx wrote:

    I use this code to set the VPBuffer's data:

    int channelCount = 4;
    Int32 bitDepth = 32;

    std::vector<float> line(pVpBuffer->GetBw() * channelCount, 1.0f); // initialize everything to 1.0 -> white

    for (Int32 y = 0; y < pVpBuffer->GetBh(); y++)
    pVpBuffer->SetLine(0, y, pVpBuffer->GetBw(), line.data(), bitDepth, false);

    It is interesting that the "Render Region" does not work but the "Interactive Render Region" does work.

    Although it could be that I'm doing it wrong because when I move the interactive region, there seems to be no redraw, but I only "see" another part of the rendered image.

    I will take a look into the render data...



  • On 09/10/2014 at 12:19, xxxxxxxx wrote:

    This is the code I wrote to test it. And it works in both the render region and the IRR.
    Although the IRR needs to be set at 100% accuracy or else it offsets the drawn shape.
    I don't know why. *Shrug*

      
    //This code turns the renderer off and draws a white square when rendering  
    //The IRR also works...But it's quality slider needs to be set to 100% for the square's position to be accurate  
      
      
    RENDERRESULT MyPostData::Execute(BaseVideoPost *node, VideoPostStruct *vps)  
    {  
      if(vps->error == nullptr || *vps->error != RENDERRESULT_OK || vps->thread->TestBreak())  
      {  
          //After skipping the render process vps->error is set, so we end up here and return  
          return RENDERRESULT_OK;  
      }  
      
      if(vps->vp == VIDEOPOSTCALL_INNER && vps->open)  
      {  
          VPBuffer *pVpBuffer = vps->render->GetBuffer(VPBUFFER_RGBA, 0);  
          MultipassBitmap *mbmp = (MultipassBitmap* )pVpBuffer;  
      
          //Set the size and position of the white square that gets drawn when rendering  
          //NOTE: The quality setting changes the position of the drawn square(Crank it up to be most accurate)  
          LONG width = 100;   
          LONG height = 100;  
          LONG xPos = 300;  
          LONG yPos = 300;  
            
          SReal *buffer = NULL;  
          buffer = GeAllocType(SReal, 512*3);  
      
          //The pixel brightness  
          for(LONG i=0; i<512*3; i++)  
              buffer[i] = 1.0;   //100%  
      
          //Cast the SReal buffer into UCHAR; inc parameter is 3*4bytes (3*32bit) because of floating point image format  
          for(LONG y=0; y<height; y++)  
              if (!mbmp->SetPixelCnt(xPos, y+yPos, width, (UCHAR* )buffer, 12, COLORMODE_RGBf, PIXELCNT_0)) return RENDERRESULT::RENDERRESULT_USERBREAK;  
      
          return RENDERRESULT::RENDERRESULT_USERBREAK;  
      }  
      
            
      return RENDERRESULT_OK;  
    }
    

    -ScottA



  • On 09/10/2014 at 12:32, xxxxxxxx wrote:

    Actually. I take that back.
    My code doesn't work properly with Render Region either.

    The color gets called and drawn no matter where the user draws on the screen with the RR tool.

    -ScottA



  • On 09/10/2014 at 14:35, xxxxxxxx wrote:

    When the interactive render region is used, I can simply use the same code as for a regular rendering and everything will work. In fact my own renderer copies the whole image back into the buffer, for example, 880x350 instead of the smaller render region, for example, 420x150. Cinema seems to only display the selected region, but that is somewhere inside C4D and has nothing to do with my code. I could of course optimize this processing and limit my computations to the selected region, but I don't care for that optimization for now.

    The other part is the "Render region" (not the interactive one). Here we have another great example how funny C4D handles similar things completely different sometimes. When using the render region C4D does not "mask" the other parts of the buffer, so I would have to take care of the top, left, right and bottom and only copy the selected parts back. The interesting thing is that I am not even sure how I would tell C4D to only display/render the selected region. Whatever... here is some code I started with:

    BaseContainer renderData = vps->render->GetRenderData();
    Bool renderRegion = renderData.GetBool(RDATA_RENDERREGION, false);
    if (renderRegion)
    	Int32 left = renderData.GetInt32(RDATA_RENDERREGION_LEFT);
    

    If anyone knows how to handle render regions in an ideal way, please tell me. Otherwise, I just don't support that feature and instead of the render region, the whole image is updated/rendered.



  • On 10/10/2014 at 03:37, xxxxxxxx wrote:

    Hi guys,
    I'm digging in to it.
    Just to make sure (still learning here, please keep this in mind), I'll use the VPColorize.cpp (C++ SDK - Selective Colorize plugin) from SDK examples as a basis. If that's wrong, please let me know, so I don't run too far into the wrong direction...
    I'll report back on my findings.



  • On 10/10/2014 at 04:23, xxxxxxxx wrote:

    I have been playing around a little and maybe I'm missing something here. But as far as I can see "Interactive Render Region" and "Render Region" work exactly the same as far as dimensions and coordinates are concerned. All you have to keep in mind is, that the interactive one, can also change its dimensions due to the quality slider (reducing the quality percentage, leads to smaller buffer, but all offsets are still correct).

    So basically, you'd do as suggested, FrozenTarzan.

    Check for RDATA_RENDERREGION, get the offsets (RDATA_RENDERREGION_LEFT,...) as needed and calculate your position and dimension taking pVpBuffer->GetBh()/GetBw() into account.
    One thing to note, which might not be obvious:
    RDATA_RENDERREGION_LEFT/_TOP/_RIGHT/_BOTTOM deliver offsets to the respective edge.
    E.g. a pixel in the right/bottom corner would have these two as zero.

    I hope this helped. If I missed anything, explaining the obvious, leaving out the actual problem, just let me know.



  • On 10/10/2014 at 07:04, xxxxxxxx wrote:

    Hey Andreas Block,

    nice to see a new moderator here! The support team needs more of you guys! :-)

    I understand that one has to take the region into account. But on the other hand it seems a bit strange that C4D behaves like this:

    When the interactive region is chosen and I leave my code as it is (simply using the WHOLE buffer and writing 1.0 to all channels), then I see this:

    And when I use the render region to select a region of interest like this:

    I get the following result:

    So the whole viewport is replaced/overlayed instead of the region only. I think that this is quite strange because the interactive render region masks the rendering automatically.

    Now there is another strange thing too. When I decide to write nothing to the buffer, I expect the outcome to be no change in the editor view. But when I simply call SkipRenderProcess and return without writing anything to the rgba buffer, then the first time happens nothing, as expected, the second time I get a gray/white-ish overlay which becomes stronger and stronger each time I click on renderpreview. Check this out:

    NOTE: This does not happen when OpenGL is enabled in the preferences! This only happens when software rendering is used in the editor!

    This is the second time a experience a strange behavior when switching between OpenGL mode and software mode. Here is a link to another (actually way more important!) problem of mine:
    https://plugincafe.maxon.net/topic/8104/10550_materialdata-fetchsample-texture-solved&KW=fetch+material&PID=40970#40970

    No one could actually help me to resolve the bug described in my thread. Maybe you can help me here too Andreas Block? :-)



  • On 10/10/2014 at 07:11, xxxxxxxx wrote:

    Before I get into the depth of your post (which I'll need a bit more time for), I just wanted to let you know, that we are more than just me 😉
    See here: Plugin Cafe forum / General Discussion: Introducing the new SDK Support Team

    Sebastian and Joey started with me. And Jean-Francois and Yannick are still with us as well. Plus a bunch of people, who will probably not appear here (or not that frequently), but who will be working on the stuff that needs to be done in the background. We just need some more time to gain knowledge and speed. So long I need to ask for a little more patience (I know, you all had a lot already)...



  • On 11/10/2014 at 13:46, xxxxxxxx wrote:

    FrozenTarzan, at first (and that's meant for everybody on this forum) please call me Andreas. The account was created for me and as far as I can see, I have no means to correct this. Andreas is my first name and at least from my side, that's enough.

    Now, for your questions:

    So the whole viewport is replaced/overlayed instead of the region only. I think that this is quite strange because the interactive render region masks the rendering automatically.

    I agree, it's strange. On the other hand, I have the feeling, that painting outside the assigned buffer region is something one is not supposed to do. And it is neither documented nor promised, that you get defined results, when doing so.
    Don't get me wrong here, I even appreciate to be notified about such anomalies. Most bugs show up, when doing the unexpected. I will report this internally, but I can't make promises, if or when this will be addressed. After all it's not exactly broken.

    I simply call SkipRenderProcess and return without writing anything to the rgba buffer

    Again, I have the feeling, this is a bit academic. Or do you have such problem, if you process the given buffer region as you are expected to.
    Like the issue before, I will forward this internally. Unless you have a valid veto, I might add.

    Here is a link to another (actually way more important!) problem of mine:

    I can already sense, you won't like my answer on this...
    I need to beg for your patience :|
    I've read the thread and I see a lot of confusion on the entire MaterialData/ShaderData topic. Unfortunately I'm not in the condition to help you... yet. Need to build up knowledge myself first. I think, we'll discuss this topic in SDK support team, and will see, which is the fastest way to get you going.



  • On 11/10/2014 at 13:48, xxxxxxxx wrote:

    I forgot: I like your way of explaining your problems. The images certainly help, to understand your problems right away. This helps us immensely.



  • On 11/10/2014 at 14:57, xxxxxxxx wrote:

    Hey Andreas,

    I can't thank you enough for your quick responses!

    The scenerio where I don't write anything to the buffer is constructed, right. But I would have expected the outcome to be a "buggy" behavior only in the selected region because the rest of the buffer would be untouched nevertheless, right? Because IF i would handle the buffer region with all its borders etc. I would leave the outside of my region as is, but as shown above not only the region seems to behave buggy, but the whole buffer.

    About the other topic. If you want I can reformulate my question about the materials because as I have my plugin right now, there is only one problem with the updates when OpenGL is enabled. I can strip down the whole thread which started with a different question. On the other hand, I would appreciate answers/tips to all described problems/questions.
    Just let me know if you want me to open a new thread or leave the current one, to minimize confusion. In fact in the thread you already find a reference to another related question of mine^^

    Thank you so much for your effort and quick answers. An answer like "please be patient" is way better than none! :-)



  • On 14/10/2014 at 05:05, xxxxxxxx wrote:

    Hello,

    you get the coordinates for rendering in the IRR or render region from the RayParameter structure provided by VolumeData. Use this coordinates to update only the relevant parts of the target buffer:

      
              Int32 x1, y1, x2, y2, x, y, cnt, i;  
            
              Int32 cpp = targetBuffer->GetInfo(VPGETINFO_CPP);  
                
              **RayParameter** * ray = vps->vd-> **GetRayParameter** ();  
                
    _             x1    = ray->left;  
              y1    = ray->top;  
              x2    = ray->right;  
              y2    = ray->bottom;  
              cnt = x2 - x1 + 1;_  
                
              Int             bufferSize = cpp * cnt;  
              Float32* b, *buffer = nullptr;  
                
              if (bufferSize > 0)  
                  buffer = NewMemClear(Float32, bufferSize);  
              if (!buffer)  
                  return;  
                
              for (y = y1; y <= y2; y++)  
              {  
                  targetBuffer->GetLine(x1, y, cnt, buffer, 32, true);  
                    
                  for (b = buffer, x = x1; x <= x2; x++, b += cpp)  
                  {  
                      for (i = 0; i < 3; i++)  
                          b[i] = 1.0f;  
                  }  
                    
                  targetBuffer->SetLine(x1, y, cnt, buffer, 32, true);  
              }  
                
              DeleteMem(buffer);  
      
      
    

    You might take a look at the VideoPostData examples in the SDK.

    best wishes,
    Sebastian



  • On 14/10/2014 at 09:17, xxxxxxxx wrote:

    Oh, that's awesome, look at this:

    I used the standard renderer of C4D. Select "render region" and let the renderer render the rectangle, fine, works... great. Then DO NOT CLICK ANYWHERE but select the "render region" again and create a new one. See what happens. This can be repeated multiple times.

    So this is a bug in C4D because the buffer should be cleared before rendering (+ blending!?). In my previous posts I described that the first rendering does not change the output, so indeed it works. That's also the case for the render region. The first one works, all additional ones fail due to missing buffer-clearing.

    To emulate the (buggy) behavior of C4D I now copy only the required pixels back and don't care, because I can't change it ;-)



  • On 15/10/2014 at 06:09, xxxxxxxx wrote:

    Hello,

    thanks for posting this. Indeed this seems to be a bug in the software viewport. It works fine in the OpenGL viewport. I filed a bug report on this issue.

    Best wishes,
    Sebastian



  • On 28/10/2014 at 02:12, xxxxxxxx wrote:

    Hey Sebastian,

    1- is this the same approach used to update render buckets?
    2- what if I want the OpenGL buffer Pointer, so I can copy directly data using CUDA, is this possible?



  • On 28/10/2014 at 06:18, xxxxxxxx wrote:

    Hello,

    Render Buckets are typically manged within your render engine, so this has nothing to do with the Render Region. For questions not related to this thread's topic please create a new topic.

    thanks & best wishes,
    Sebastian



  • On 28/10/2014 at 07:02, xxxxxxxx wrote:

    Hi Sebastian,

    I know that the buckets themselves are managed by my render engine, I just want to update the buffer so the user can see the progress while rendering

    didn't want to create a new thread as I thought the approach of updating buffer is written in this thread
    edit: I'm posting a new thread, so forget about my question here


Log in to reply