VPBUFFER_OBJECTBUFFER is not rendered correctly



  • Hello.

    I've got two problems regarding the generating of object buffers in picture viewer for my VideoPostData.

    1) I create a scene with object buffers enabled and I allocate them in my VideoPostData using

    render->AllocateBuffer(VPBUFFER_MAT_NORMAL, 0, 8, true);
    render->AllocateBuffer(VPBUFFER_SHADOW, 0, 8, true);
    render->AllocateBuffer(VPBUFFER_OBJECTBUFFER, 1, 8, true);
    render->AllocateBuffer(VPBUFFER_OBJECTBUFFER, 2, 8, true);

    The first time I render the scene, everything appears great, but if I render again without changing anything, the object buffers appear black.

    2) SetLine require differnt format in their void* data depending on their VPBUFFER_.
    For example, if I use VPBUFFER_OBJECTBUFFER, it requires a greyscale buffer. For instance, if the image is 16 x 16, each line (void
    data) has to be 16 bytes.
    If I SetLine to VPBUFFER_RGBA, each line has to be 16 * 4 bytes. Is this how it is supposed to be ?

    Thank you very much for your time !


  • Global Moderator

    Hi Petros, sorry for getting late here.

    I've tried to replicate the behavior you're reporting, but unfortunately I've succeeded in.
    The way i usually handle buffer fill-up in VPData is :

    ...
    VPBuffer* rgba = render->GetBuffer(VPBUFFER_RGBA, 0);
    Int32 rgbaBufferCPP = NOTOK, rgbaBufferDepth = NOTOK, rgbaBufferWidth = NOTOK, rgbaBufferHeight = NOTOK;
    if (rgba)
    {
        rgbaBufferCPP = rgba->GetInfo(VPGETINFO::CPP);
        rgbaBufferDepth = rgba->GetInfo(VPGETINFO::BITDEPTH);
        rgbaBufferWidth = rgba->GetInfo(VPGETINFO::XRESOLUTION);
        rgbaBufferHeight = rgba->GetInfo(VPGETINFO::YRESOLUTION);
        DiagnosticOutput("rgbaBuffer: @ / @ / @ / @", rgbaBufferCPP, rgbaBufferDepth, rgbaBufferWidth, rgbaBufferHeight);
        
        if (rgbaBufferDepth == 32)
        {
            iferr (rgbaBuffer = NewMemClear(Float32, rgbaBufferWidth * rgbaBufferCPP))
            {
                CriticalOutput("Failed to allocate rgba 32-bit buffer");
                return RENDERRESULT::OUTOFMEMORY;
            };
        }
        else
        {
            iferr (rgbaBuffer = NewMemClear(UChar, rgbaBufferWidth * rgbaBufferCPP))
            {
                CriticalOutput("Failed to allocate rgba 8-bit buffer");
                return RENDERRESULT::OUTOFMEMORY;
            };
        }
    }
    
    Float percent = 0.0;
    while (percent < 1.0)
    {
        for (Int32 i = 0; i < rgbaBufferHeight; i++)
        {
            if (rgbaBuffer)
            {
                if (rgbaBufferDepth == 32)
                    r_gigante::FillBufferWithRandomValues((Float32*)rgbaBuffer, rgbaBufferWidth, rgbaBufferCPP);
                else
                    r_gigante::FillBufferWithRandomValues((UChar*)rgbaBuffer, rgbaBufferWidth, rgbaBufferCPP);
            
                rgba->SetLine(0, i, rgbaBufferWidth, rgbaBuffer, rgbaBufferDepth, true);
            }
            
            if (thread->TestBreak())
            {
                if (rgbaBuffer)
                    DeleteMem(rgbaBuffer);
                return RENDERRESULT::USERBREAK;
            }
        }
    } 
    ...
    

    where FillBufferWithRandomValues is

    void FillBufferWithRandomValues(Float32* buffer, UInt32 bufferSize, UInt32 channels/* = 4*/)
    {
    	Random rng;
    	rng.Init(UInt32(rand()));
    	if (channels == 4)
    	{
    		for (UInt32 i = 0; i < bufferSize; i++)
    		{
    			buffer[i * channels + 0] = Float32(rng.Get01());
    			buffer[i * channels + 1] = Float32(rng.Get01());
    			buffer[i * channels + 2] = Float32(rng.Get01());
    			buffer[i * channels + 3] = Float32(0);
    		}
    		return;
    	}
    	
    	if (channels == 3)
    	{
    		for (UInt32 i = 0; i < bufferSize; i++)
    		{
    			buffer[i * channels + 0] = Float32(rng.Get01());
    			buffer[i * channels + 1] = Float32(rng.Get01());
    			buffer[i * channels + 2] = Float32(rng.Get01());
    		}
    		return;
    	}
    	
    	if (channels == 1)
    	{
    		for (UInt32 i = 0; i < bufferSize; i++)
    		{
    			buffer[i * channels + 0] = Float32(rng.Get01());
    		}
    		return;
    	}
    }
    

    (NOTE - in my code the FillBufferWithRandomValues has definition for both 8-bit and 32-bit buffers)

    If you can provide with a complete example showing your issue, I'd be glad to look into, but being blind to your code I really can't be more helpful.
    With regard to the second question, I think the above code properly answers here.

    In case you got your issue fixed, please mark this thread as solved.

    Best, Riccardo



  • Hello.

    I made come changes and it works now.
    It appears that I was handling VPBuffers incorrectly.
    Just to be sure, we allocate the buffers using AllocateBuffer and they are deallocated automatically correct ?
    When does the deallocation take place ?

    Thank you for your time !


  • Global Moderator

    Hi Petros, glad that you get it fixed.

    With regard to buffer allocation via AllocateBuffer, being those buffer handled by Cinema, they are automatically released as soon as the multipass bitmap containing such buffers are passed to the PictureViewer.

    Best, Riccardo