Rendering Large Images
Introduction
In today graphics, a lot of images need big resolutions. In fact, resolutions can be so high that you can’t even think about rendering them in a single video buffer. You may also need to render parts of a same image onto different displays. HOOPS Luminate provides an easy way to split an image calculation in buckets of pixels that can be later reassembled into the whole image: the asymmetric camera (see Viewpoints).
Description
In this tutorial, we’ll render a large images made of 16 buckets of pixels using HOOPS Luminate asymmetric cameras. As usual, we start by setuping a simple scene: a collection of coloured boxes lit by a single spotlight.
Then, the rendering is split into 16 passes. Each pass renders 1/16th of the whole image using an asymmetric camera.
The rendering then consists of a 4x4 loop:
// Computes the 16 image chunks.
for( int y = 0; y < 4; ++y )
{
for( int x = 0; x < 4; ++x )
{
while( ( RFK::TutorialApplication::GetTime() - last_time ) < 1000.0f ) {}
last_time = RFK::TutorialApplication::GetTime();
float tfov = tanf( fov );
float tfovleft = tfov - x * 2.f * tfov / 4.f;
float tfovright = -tfov + ( x + 1 ) * 2.f * tfov / 4.f;
float tfovbottom = ratio * ( tfov - ( 3 - y ) * 2.f * tfov / 4.f );
float tfovtop = ratio * ( -tfov + ( 4 - y ) * 2.f * tfov / 4.f );
RC_TEST( iviewpoint->SetAsymmetricFrustumPerspective( atanf( tfovleft ), atanf( tfovright ),
atanf( tfovbottom ), atanf( tfovtop ),
iresmgr->GetState() ) );
RFK::TutorialApplication::UpdateProgressBar( ( x + y * 4 + 1 ) / 16.f );
RC_TEST( RFK::TutorialApplication::Invalidate() );
// Blits the chunk pixels into the output image.
RC_TEST( iimg2d->GetPixels() );
unsigned char* pixels = iimg2d->GetLocalPixels();
unsigned char* dst = output + 4 * ( ( 3 - y ) * h * ww + x * w );
unsigned char* src = pixels;
for( int line = 0; line < h; ++line )
{
memcpy( dst, src, 4 * w );
dst += 4 * ww;
src += 4 * w;
}
}
}
For each new bucket to render, the corresponding asymmetric camera is setup. After the bucket rendering, the rendered pixels are get back using a RED render image (see RED::IImage2D::SetRenderImage
) and immediately blit into the final hi-res image.
Finally, the hi-res image is saved to the disk using the RED::ImageTools API
.