IRhRdkRenderWindow::SetValueRect crashes when passing uchar4 buffer

I am building a custom renderer based on the SampleRealTimeRenderer.
I receive my image buffer in a uchar4 form, but when I try to call the SetValueRect function I am always getting an exception.


std::vector<uchar4> output_buffer_new(width * height);
pChannel->SetValueRect(0, 0, width, height, width * sizeof(uchar4), ComponentOrder::RGBA, output_buffer_new.data());

On the contrary, if I normalize the values of output_buffer_new by dividing by 255.0 and provide a float4 buffer, everything seems to work properly.

std::vector<float4> output_buffer_fl4(width* height)
for (int i = 0; i < lums.size(); i++) {
output_buffer_fl4.at(i).x = static_cast<float> (output_buffer_new[i].x / 255.0);
output_buffer_fl4.at(i).y = static_cast<float> (output_buffer_new[i].y / 255.0);
output_buffer_fl4.at(i).z = static_cast<float> (output_buffer_new[i].z / 255.0);
output_buffer_fl4.at(i).w = static_cast<float> (output_buffer_new[i].w / 255.0);
}

pChannel->SetValueRect(0, 0, state.params.width, state.params.height, state.params.width * sizeof(float4), ComponentOrder::RGBA, output_buffer_fl4.data());

Is there something I should do in order to have SetValueRect accept uchar4 buffer?
Thanks!

@johnc , can you help here?

Hi @fatecasino,

If you are using the standard RGBA channel (IRhRdkRenderWindow::chanRGBA) then each component of each pixel is a float. If you just pass your uchar4 buffer, the pixel format will be wrong and the buffer will be too small which could be why you are getting an exception.

Your solution is correct; the 4 bytes have to be converted to 4 floats to be used with the standard RGBA channel.

The reason SetValueRect takes a void pointer is to support custom channels which might not take floats. But for standard channels you have to think of it as a float pointer.

If you look at class RHRDK_SDK IChannel and the PixelSize function, this is mentioned in the comments. This is easy to miss, so I will add extra comments to the other relevant functions to make it clearer.

Regards,

John

thanks for your answer, it took me some time to realize that SetValueRect does not take uchar buffers. Would you consider overloading this function? in some cases where this minimum amount of information is sufficient (4 bytes) it could potentially increase rendering performance if we could insert a uchar buffer instead of a float one.

Hi @fatecasino,

I understand your concern about performance, but the rendering pipeline operates on high dynamic range data, hence the input must be floats. It’s not possible to avoid the conversion when using the built-in RGBA channels. If I were to overload the function, I would just be moving the conversion code into Rhino.

John

2 Likes