RenderEngineContext vs. RenderQueue

<< Click to Display Table of Contents >>

Navigation:  XStream® HDVR® SDK > Implementation Concepts > Rendering Concepts >

RenderEngineContext vs. RenderQueue

Previous pageReturn to chapter overviewNext page

C++ C++ Java Java .NET .NET

Summary

 

The XStream® HDVR® SDK supports two rendering class types: IRenderEngineContext (hdrcRenderEngineContext) and IRenderQueue (hdrcRenderQueue). The IRenderEngineContext or hdrcRenderEngineContext class provides a synchronous rendering mechanism that allows for a deterministic relationship between an applied set of rendering state parameters in a RENDER_PARAMS structure, and the next frame to be generated by the rendering server application. The IRenderQueue or hdrcRenderQueue class provides an asynchronous rendering mechanism that works through callback class methods. The IRenderEngineContext or hdrcRenderEngineContext is described first, and provides more control over how the application handles rendering of individual frames. However, the IRenderQueue or hdrcRenderQueue class provides a higher level abstraction that automates and simplifies some elements of the rendering process, including automatic generation of interactive and final quality images, and decoding of JPEG compressed frames for the client. Both classes support high speed rendering.

 

The IRenderQueue or hdrcRenderQueue class is recommended for most end user applications.

 

RenderEngineContext

 

The IRenderEngineContext class provides a synchronous rendering mechanism. Frames are only generated by the rendering server in response to explicit calls to IRenderEngineContext rendering methods. This differs from the IRenderQueue class that automatically generates a pair of interactive and final quality images as appropriate, depending on the frequency of rendering calls. The rendering calls in IRenderEngineContext are blocking, and will not return until a new frame is available from the rendering server.

 

There are two primary rendering methods in the IRenderEngineContext class: IRenderEngineContext::Render() and IRenderEngineContext::RenderStreamed(). The most straightforward rendering method in the class is IRenderEngineContext::Render(). It initiates the rendering of a single frame and returns when the frame is complete. The render parameters used to generate the frame are set by the most recent call to IRenderEngineContext::SetRenderParams(). The IRenderEngineContext::RenderStreamed() method allows the client application to simultaneously retrieve the most recently rendered frame, set a RENDER_PARAMS structure for the next frame, and begin a new render pass.

 

IRenderEngineContext::Render() Method

 

The IRenderEngineContext::Render() method takes two VOLVISIMAGE objects. The first object specifies input parameters that designate the image rendering quality, and the second object is the output parameter with reference to the rendered data. The input VOLVISIMAGE::Stage parameter must be set to an appropriate ENUM_RENDER_STAGE enumeration value. This will be either RENDER_STAGE_PROG0 for an interactive quality image or RENDER_STAGE_FINAL for a final high quality image. It is the responsibility of the application to call Render() at least once to generate an interactive rendering followed by the final rendering. The IRenderEngineContext class progressively builds upon the data computed during the interactive phase to produce the final quality rendering, without any negative performance impact due to the multiple render calls. This level of detail is hidden in the IRenderQueue class.

 

The IRenderEngineContext::Render() method returns the image data and corresponding member fields to the client through the output VOLVISIMAGE parameter. The actual image data is in the VOLVISIMAGE::Data member. It is important to deallocate the memory stored in the VOLVISIMAGE::Data member once the operation is complete, or a memory leak will result.

 

It is important to deallocate the memory stored in the VOLVISIMAGE::Data member once the operation is complete, or a memory leak will result.

 

Optionally, compressed data may be transmitted by the server when the appropriate ENUM_COMPRESSION_TYPE value is specified in VOLVISIMAGE::CompressionType. Typically, COMPRESSION_TYPE_JPEG is used for interactive, and COMPRESSION_TYPE_NONE for the final rendering. When JPEG compression is specified, the VOLVISIMAGE::CompressionParam member must specify the compression quality: 0 (lowest) to 100 (highest).

 

 

When a compressed data type parameter is set in VOLVISIMAGE::CompressionType, it is important to also set the VOLVISIMAGE::CompressionParam parameter to define this value
 
The IRenderEngineContext class will not automatically decode the JPEG data to raw RGB data for the output buffer, so it is the responsibility of the client application to perform the JPEG decode step when transmitting compressed data.

 

 

// Create an IRenderEngineContext object

IRenderEngineContext *pRenderEngine;

pServerContext->CreateRenderEngine(&pRenderEngine, RECID_PAR);

 

// Initialize the render engine with the volume and octree data

pRenderEngine->SetVolumeData(pVolumeData, pOctreeData);

 

// Set the IRenderEngineContext render paramaters.

RENDER_PARAMS rp;

pServerContext->LoadPreset("C:/data/preset.xml", &rp);

pRenderEngine->SetRenderParams(&rp);

 

// Set input VOLVISIMAGE data.

VOLVISIMAGE imgReq, imgRes;

BCOM_ZEROMEMORY(imgReq);

BCOM_ZEROMEMORY(imgRes);

 

// Request an interactive quality image.

imgReq.Stage = RENDER_STAGE_PROG0;

 

// Set for JPEG compression.

imgReq.CompressionType = COMPRESSION_TYPE_JPEG;

imgReq.CompressionParam = 90;

                                                 

// Render an interactive quality frame

pRenderEngine->Render(&imgReq, &imgRes);

 

// Request a final quality image.

imgReq.Stage = RENDER_STAGE_FINAL;

 

// Set quality to maximum for final image.

VOLVISIMAGE::CompressionParam = 100;

 

// Render a final quality frame

pRenderEngine->Render(&imgReq, &imgRes);

 

// Deallocate image with allocator class when done with data.

IAllocator *pAllocator;

pLibrary->GetAllocator(HCAP_IMAGE, &pAllocator);

pAllocator->Free(imgRes.Data);

 

The hdrcRenderEngineContext class provides a synchronous rendering mechanism. Frames are only generated by the rendering server in response to explicit calls to hdrcRenderEngineContext rendering methods. This differs from the hdrcRenderQueue class that automatically generates a pair of interactive and final quality images as appropriate, depending on the frequency of rendering calls. The rendering calls in hdrcRenderEngineContext are blocking, and will not return until a new frame is available from the rendering server.

 

There are two primary rendering methods in the hdrcRenderEngineContext class: hdrcRenderEngineContext.render() and hdrcRenderEngineContext.renderStreamed(). The most straightforward rendering method in the class is hdrcRenderEngineContext.render(). It initiates the rendering of a single frame and returns when the frame is complete. The render parameters used to generate the frame are set by the most recent call to hdrcRenderEngineContext.setRenderParams(). The hdrcRenderEngineContext.renderStreamed() method allows the client application to simultaneously retrieve the most recently rendered frame, set a RENDER_PARAMS structure for the next frame, and begin a new render pass.

 

hdrcRenderEngineContext::render() Method

 

The hdrcRenderEngineContext.render() method takes two VOLVISIMAGE objects. The first object specifies input parameters that designate the image rendering quality, and the second object is the output parameter with reference to the rendered data. The input VOLVISIMAGE.Stage parameter must be set to an appropriate ENUM_RENDER_STAGE enumeration value. This will be either RENDER_STAGE_PROG0 for an interactive quality image, or RENDER_STAGE_FINAL for a final high quality image. It is the responsibility of the application to call hdrcRenderEngineContext.render() at least once to generate an interactive rendering followed by the final rendering. The hdrcRenderEngineContext class progressively builds upon the data computed during the interactive phase to produce the final quality rendering without any negative performance impact due to the multiple render calls. This level of detail is hidden in the hdrcRenderQueue class.

 

The hdrcRenderEngineContext.render() method returns the image data and corresponding member fields to the client is through the output VOLVISIMAGE parameter. The actual image data is in the VOLVISIMAGE.Data member and will automatically be garbage collected once the operation is complete.

 

Optionally, compressed data may be transmitted by the server when the appropriate ENUM_COMPRESSION_TYPE value is specified in VOLVISIMAGE.CompressionType. Typically, COMPRESSION_TYPE_JPEG is used for interactive, and COMPRESSION_TYPE_NONE for the final rendering. When JPEG compression is specified, the VOLVISIMAGE.CompressionParam member must specify the compression quality: 0 (lowest) to 100 (highest).

 

When a compressed data type parameter is set in VOLVISIMAGE.CompressionType, it is important to also set the VOLVISIMAGE.CompressionParam parameter to define this value
 
The hdrcRenderEngineContext class will not automatically decode the JPEG data to raw RGB data for the output buffer, so it is the responsibility of the client application to perform the JPEG decode step when transmitting compressed data.

 

 

// Create the hdrcRenderEngineContext object.

hdrcRenderEngineContext renderEngine;

renderEngine = serverContext.createRenderEngine(hdrcDefines.RENDER_ENGINE_ID_PAR);

 

// Set the hdrcVolumeDataContext and hdrcOctreeContex.

renderEngine.setVolumeData(volumeData, octreeData);

 

// Set the IRenderEngineContext render parameters.

RENDER_PARAMS rp = new RENDER_PARAMS;

serverContext.loadPreset("C:/data/preset.xml", rp);

renderEngine.setRenderParams(rp);

 

// Set input VOLVISIMGE data.

VOLVISIMAGE imgReq = new VOLVISIMAGE(); 

VOLVISIMAGE imgRes = new VOLVISIMAGE(); 

 

// Request an interactive quality image.

imgReq.Stage = hdrcDefines.RENDER_STAGE_PROG0;

 

// Set for JPEG compression.

imgReq.CompressionType = hdrcDefines.COMPRESSION_TYPE_JPEG;

imgReq.CompressionParam = 90;

 

// Render an interactive quality frame

renderEngine.render(imgReq, imgRes);

 

// Request a final quality image.

imgReq.Stage = hdrcDefines.RENDER_STAGE_FINAL;

 

// Set quality to maximum for final image.

imgReq.CompressionParam = 90;

 

// Render a final quality frame

renderEngine.render(imgReq, imgRes);

 

// Create the hdrcRenderEngineContext object.

hdrcRenderEngineContext renderEngine;

renderEngine = serverContext.createRenderEngine(hdrcDefines.__Fields.RENDER_ENGINE_ID_PAR);

 

// Set the hdrcVolumeDataContext and hdrcOctreeContex.

renderEngine.setVolumeData(volumeData, octreeData);

 

// Set the IRenderEngineContext render parameters.

RENDER_PARAMS rp = new RENDER_PARAMS;

serverContext.loadPreset("C:/data/preset.xml", rp);

renderEngine.setRenderParams(rp);

 

// Set input VOLVISIMGE data.

VOLVISIMAGE imgReq = new VOLVISIMAGE(); 

VOLVISIMAGE imgRes = new VOLVISIMAGE(); 

 

// Request an interactive quality image.

imgReq.Stage = hdrcDefines.__Fields.RENDER_STAGE_PROG0;

 

// Set for JPEG compression.

imgReq.CompressionType = hdrcDefines.__Fields.COMPRESSION_TYPE_JPEG;

imgReq.CompressionParam = 90;

 

// Render an interactive quality frame

renderEngine.render(imgReq, imgRes);

 

// Request a final quality image.

imgReq.Stage = hdrcDefines.__Fields.RENDER_STAGE_FINAL;

 

// Set quality to maximum for final image.

imgReq.CompressionParam = 90;

 

// Render a final quality frame

renderEngine.render(imgReq, imgRes);

 

IRenderEngineContext::RenderStreamed() Method

 

As with the IRenderEngineContext::Render() method, the IRenderEngineContext::RenderStreamed() method takes two VOLVISIMAGE objects. The first object specifies input parameters that designate the image rendering quality, and the second object is the output parameter with reference to the rendered data. The IRenderEngineContext::RenderStreamed() method also takes an input RENDER_PARAMS structure to set the rendering parameters for the next render pass and simultaneously requests the current frame, allowing the server application to begin rendering the next frame as soon as the previous frame completes. An advantage of the IRenderEngineContext::RenderStreamed() method is ensuring that the rendering engine is always fully engaged, with no idle time between render passes. When used optimally, this method begins rendering the next frame before the client application has even received the previous frame. If the server application has not completed rendering the current frame, the IRenderEngineContext::RenderStreamed() call will block until the next frame is available.

 

 

Do not call IRenderEngineContext::SetRenderParams() when rendering is in progress using the IRenderEngineContext::RenderStreamed() method. Doing so will terminate the current render pass in progress.

 

Generally, the IRenderEngineContext::RenderStreamed() method is called multiple times in sequence to begin, continue, and stop a rendering sequence. A render sequence is started with a call to IRenderEngineContext::RenderStreamed() using NULL for the first parameter, to indicate that no previous frame exists for this rendering sequence.

 

// Begin a RenderStreamed sequence.

pRenderEngine->RenderStreamed(NULL, &rp, &nextImage);

 

Once a render sequence has started, it continues with successive calls to IRenderEngineContext::RenderStreamed(), which contains VOLVISIMAGE structures for both the previous frame and the next frame, as well as a RENDER_PARAMS structure to set parameters for the next frame.

 

// Continue a RenderStreamed sequence with successive calls.

pRenderEngine->RenderStreamed(&prevImage, &rp, &nextImage);

 

When the rendering sequence has completed, IRenderEngineContext::RenderStreamed() is called with only a VOLVISIMAGE structure for the last frame rendered. The other two input parameters are NULL.

 

// Terminate a RenderStreamed sequence with NULL for the input parameters.

pRenderEngine->RenderStreamed(&prevImage, NULL, NULL);

 

hdrcRenderEngineContext.renderStreamed() Method

 

As with the hdrcRenderEngineContext.render() method, the hdrcRenderEngineContext.renderStreamed() method takes two VOLVISIMAGE objects. The first object specifies input parameters that designate the image rendering quality, and the second object is the output parameter with reference to the rendered data. The hdrcRenderEngineContext.renderStreamed() method also takes an input RENDER_PARAMS structure to set the rendering parameters for the next render pass and simultaneously requests the previous frame, allowing the server application to begin rendering the next frame as soon as the previous frame completes. An advantage of the hdrcRenderEngineContext.renderStreamed() method is ensuring that the rendering engine is always fully engaged, with no idle time between render passes. When used optimally, this method begins rendering the next frame before the client application has even received the previous frame. If the server application has not completed rendering the current frame, the hdrcRenderEngineContext.renderStreamed() call will block until the next frame is available.

 

 

Do not call hdrcRenderEngineContext.setRenderParams() when rendering is in progress using the hdrcRenderEngineContext.renderStreamed() method. Doing so will terminate the current render pass in progress.

 

Generally, the hdrcRenderEngineContext.renderStreamed() method is called multiple times in sequence to begin, continue, and stop a rendering sequence. A render sequence is started with a call to hdrcRenderEngineContext.renderStreamed() using NULL for the first parameter, to indicate that no previous frame exists for this rendering sequence.

 

// Begin a RenderStreamed sequence.

renderEngine.renderStreamed(null, rp, nextImage);

 

Once a render sequence has started, it continues with successive calls to hdrcRenderEngineContext.renderStreamed(), which contains VOLVISIMAGE structures for both the previous frame and the next frame, as well as a RENDER_PARAMS structure to set parameters for the next frame.

 

// Continue a RenderStreamed sequence with successive calls.

renderEngine.renderStreamed(prevImage, rp, nextImage);

 

When the rendering sequence has completed, hdrcRenderEngineContext.renderStreamed() is called with only a VOLVISIMAGE structure for the last frame rendered. The other two input parameters are NULL.

 

// Terminate a RenderStreamed sequence with NULL for the input parameters.

renderEngine.renderStreamed(prevImage, NULL, NULL);

 

RenderQueue

 

 

IRenderQueue is the recommended rendering class for most applications.

 

 

The IRenderQueue class is the second of the two rendering classes available in the XStream® HDVR® SDK. The IRenderQueue provides an asynchronous rendering mechanism that initiates rendering and returns immediately, in contrast to the IRenderEngineContext class that blocks until the rendered frame is available. When a rendered frame is complete, it is returned through a callback method mechanism. The IRenderQueue class provides a simpler abstraction than the IRenderEngineContext, because it automates certain aspects of the rendering process. For example, the IRenderQueue class generates pairs of interactive and final quality frames, and decodes JPEG compressed images on the client. Due to the asynchronous nature of the IRenderQueue, there is no deterministic relationship between IRenderQueue::SetRenderParams() calls and the next frame generated by the server, thus changes to the rendering parameters are unrestricted.

 

The first step in rendering with the IRenderQueue class is to set a callback class that implements the IRQFrameListener interface. The rendering server will then automatically invoke the callback to deliver frames to the client application. When a frame is ready to be delivered to the client, the server calls IRQFrameListener::RawFrameReady() method. The input parameters for this method contain the image data in a VOLVISIMAGE structure, the render parameters used to render the frame in a RENDER_PARAMS structure, and a flag designating the frame quality as interactive or final.

 

The IRenderQueue::SetCompressionType() method can be used to set image compression. If compressed images are used, then the image data that is passed to the IRQFrameListener::RawFrameReady() method is compressed. Otherwise, the image will contain uncompressed RGB data. Uncompressed data can be used directly from IRQFrameListener::RawFrameReady(), or passed to IRQFrameListener::ConvertedFrameReady() as decompressed data.

 

The client will then access the image through the VOLVISIMAGE structure.

 

Once the IRQFrameListener class has been defined, it is set as the frame receiver for the IRenderQueue object with the IRenderQueue::SetFrameListener() method.

 

// Define an IRQFrameLisener class

class IRQFrameListenerUserDefined : public IRQFrameListener

{

public:

  BCOM_METHOD(RRESULT, RawFrameReady)(h_boolean *pRet, const VOLVISIMAGE *imm, const RENDER_PARAMS *rp, const h_boolean bFinal);

  BCOM_METHOD(RRESULT, ConvertedFrameReady)(const VOLVISIMAGE *pImage, const RENDER_PARAMS *rp);

  BCOM_METHOD(RRESULT, DiscardedFrame)(const RENDER_PARAMS *revertToThese);

};

 

Once an IRQFrameListener has been set with the IRenderQueue::SetFrameListener(), the IRenderQueue object is ready for rendering. The render parameters are set with the IRenderQueue::SetRenderParams() method, and will automatically initiate a render pass if the render engine is idle. Once the IRQFrameListener and RENDER_PARAMS are set, the IRenderQueue::Render() method can be called to instruct the server to render a frame if the render engine is idle. This may be desired if changes are made to the dataset through mechanisms other than the IRenderQueue::SetRenderParams() call, such as applying segmentation or changing the transfer function settings. If the render engine is busy rendering a frame, calls to IRenderQueue::Render() are ignored, and calls to IRenderQueue::SetRenderParams() will only queue a new set of RENDER_PARAMS.

 

Calling the IRenderQueue::SetRenderParams() or IRenderQueue::Render() rendering methods in quick succession will not necessarily produce multiple frames from the rendering server. If the rendering server is already engaged in rendering a frame, calls to IRenderQueue rendering methods are ignored. This is in contrast to the IRenderEngineContext rendering methods which always produce one frame per call due to its synchronous design pattern.

 

 

// Create an IRenderQueue object

IRenderQueue *pRenderQueue;

pLibrary->CreateObject(&CLSID_RenderQueue, pRenderQueue);

 

// Initialize the render engine with the volume and octree data

pRenderQueue->Init(pServerContext, pVolumeData, pOctreeData);

 

// Set the IRQFrameListener.

// The IRQFRameListenerUserDefined class is defined by the user and inherits from IRQFrameListener.

IRQFRameListenerUserDefined frameListener;

pRenderQueue->SetFrameListener(&frameListener);

 

// Set the IRenderEngineContext render parameters.

RENDER_PARAMS rp;

pServerContext->LoadPreset("C:/data/preset.xml", &rp);

pRenderQueue->SetRenderParams(&rp);

 

// Render an interactive quality frame

pRenderQueue->Render();

 

The image quality (interactive or final) is dictated by the server, based on the delay between successive IRenderQueue::Render() calls. Unlike IRenderEngineContext, no VOLVISIMAGE image request object is passed to the IRenderQueue::Render() method, so the timing between calls determines whether the image quality is interactive or final. If the interval of time between successive IRenderQueue::Render() calls is shorter than the timeout value, only interactive quality images are rendered. Once the timeout value is reached, the server will automatically generate a final quality image. While the default final frame timeout value is one second, it can be modified through the IRenderQueue::SetFinalRenderTimeout() method based on the application requirements. The engine can be explicitly directed to render a final quality image by calling IRenderQueue::RenderFinal().

 

Compression between the client and server is enabled through the IRenderQueue::SetCompressionType() method.

 

It is important to understand how the server handles render requests and rendering parameter changes that occur between multiple render calls. When a call is made to IRenderQueue:Render() or IRenderQueue::SetRenderParams(), the most recently specified RENDER_PARAMS will be used if the rendering server is idle. However, if the rendering server is in the process of rendering a frame, the call to IRenderQueue:Render() will be ignored, and calls to IRenderQueue::SetRenderParams() will queue a new set of RENDER_PARAMS, but no new frame will be generated.

 

Any call to IRenderQueue::SetRenderParams() will trigger an implicit Render(). Note that invoking IRenderQueue::Render() will not impact performance or cause unnecessary rendering.

 

Consider the following code example. In this example a set of RENDER_PARAMS is set and a new render pass begins automatically. Then a second set of RENDER_PARAMS is sent. Because the render engine is already rendering the first set of RENDER_PARAMS, the new RENDER_PARAMS are queued up for the next server rendering pass, but no new frame is actually generated. In this case the client will not receive an image with the second set of RENDER_PARAMS. The client application must wait until the rendering server has completed the first frame before it can begin to render another frame with the new RENDER_PARAMS set. To check the status of the rendering server a call can be made to IRenderQueue::IsRendering().

 

// Set RENDER_PARAMS set 1.

pRenderQueue->SetRenderParams(&rp1);

 

// Set RENDER_PARAMS set 2.

pRenderQueue->SetRenderParams(&rp2);

 

 

hdrcRenderQueue is the recommended rendering class for most applications.

 

The hdrcRenderQueue class is the second of the two rendering classes available in the XStream® HDVR® SDK. The hdrcRenderQueue provides an asynchronous rendering mechanism that initiates rendering and returns immediately, in contrast to the hdrcRenderEngineContext class that blocks until the rendered frame is available. When a rendered frame is complete, it is returned through a callback method mechanism. The hdrcRenderQueue class provides a simpler abstraction than the hdrcRenderEngineContext, because it automates certain aspects of the rendering process. For example, the hdrcRenderQueue class generates pairs of interactive and final quality frames, and decodes JPEG compressed images on the client. Due to the asynchronous nature of the hdrcRenderQueue, there is no deterministic relationship between hdrcRenderQueue.setRenderParams() calls and the next frame generated by the server, thus changes to the rendering parameters are unrestricted.

 

The first step in rendering with the hdrcRenderQueue class is to set a callback class that implements the hdrcRQFrameListener interface. The rendering server will then automatically invoke the callback to deliver frames to the client application. When a frame is ready to be delivered to the client, the server calls hdrcRQFrameListener.convertedFrameReady() method. The input parameters for this method contain the image data in a VOLVISIMAGE structure, the render parameters used to render the frame in a RENDER_PARAMS structure, and a flag designating if the frame quality as interactive or final.

 

The hdrcRenderQueue.setCompressionType() method can be used to set image compression. If compressed images are used, then the image data that is passed to the hdrcRQFrameListener.rawFrameReady() method is compressed. Otherwise, the image will contain uncompressed RGB data. Uncompressed data can be used directly from hdrcRQFrameListener.rawFrameReady(), or passed to hdrcRQFrameListener.convertedFrameReady() as decompressed data.

 

In Java, the client will then access the image through the Java Image class object returned from hdrcRQFrameListener.convertedFrameReady() method.

 

In .NET, the client will then access the image through the VOLVISIMAGE structure.

 

Once the IRQFrameListener class has been defined, it is set as the frame receiver for the hdrcRenderQueue object with the hdrcRenderQueue.setFrameListener() method.

 

// Define a hdrcRQFrameLisener class

class hdrcRQFrameListenerUserDefined : public hdrcRQFrameListener

{

public:

  boolean rawFrameReady(VOLVISIMAGE *imm, RENDER_PARAMS rp, boolean bFinal);

  void convertedFrameReady(Image image, RENDER_PARAMS rp);

  void discardedFrame(RENDER_PARAMS revertToThese);

};

 

Once an hdrcRQFrameListener has been set with the hdrcRenderQueue.setFrameListener(), the hdrcRenderQueue object is ready for rendering. The render parameters are set with the hdrcRenderQueue.setRenderParams() method, and will automatically initiate a render pass if the render engine is idle. Once the hdrcRQFrameListener and RENDER_PARAMS are set, the hdrcRenderQueue.render()  method can be called to instruct the server to render a frame if the render engine is idle. This may be desired if changes are made to the dataset through mechanisms other than the IRenderQueue::SetRenderParams() call, such as applying segmentation or changing the transfer function settings. If the render engine is busy rendering a frame, calls to hdrcRenderQueue.render() will be ignored, and calls to hdrcRenderQueue.setRenderParams() will only queue a new set of RENDER_PARAMS.

 

Calling the hdrcRenderQueue.setRenderParams() or hdrcRenderQueue.render() rendering methods in quick succession will not necessarily produce multiple frames from the rendering server. If the rendering server is already engaged in rendering a frame, calls to hdrcRenderQueue rendering methods are ignored. This is in contrast to the hdrcRenderEngineContext rendering methods, which always produce one frame per call due to its synchronous design pattern.

 

// Create a hdrcRenderQueue object

hdrcRenderQueue renderQueue = new hdrcRenderQueue()

 

// Initialize the render engine with the volume and octree data

renderQueue.init(serverContext, volumeData, octreeData);

 

// Set the hdrcRQFrameListener.

// The hdrcRQFrameListenerUserDefined class is defined by the user and inherits from hdrcRQFrameListener.

hdrcRQFrameListenerUserDefined frameListener = new hdrcRQFrameListenerUserDefined();

renderQueue.setFrameListener(frameListener);

 

// Set the hdrcRenderEngineContext render parameters.

RENDER_PARAMS rp;

serverContext.loadPreset("C:/data/preset.xml", rp);

renderQueue.setRenderParams(rp);

 

// Render an interactive quality frame

renderQueue->render();

 

The image quality (interactive or final) is dictated by the server, based on the delay between successive hdrcRenderQueue.render() calls. Unlike hdrcRenderEngineContext, there is no VOLVISIMAGE image request object is passed to the hdrcRenderQueue.render() method, so the timing between the calls determines whether the image quality is interactive or final. If the interval of time between successive hdrcRenderQueue.render() calls is shorter than the timeout value, only interactive quality images are rendered. Once the timeout value is reached, the server will automatically generate a final quality image. While the default final frame timeout value is one second, it can be modified through the hdrcRnderQueue.setFinalRenderTimeout() method based on the application requirements. The engine can be explicitly directed to render a final quality image by calling hdrcRenderQueue.renderFinal().

 

Compression between the client and server is enabled through the hdrcRenderQueue.setCompressionType() method.

 

It is important to understand how the server handles render requests and rendering parameter changes that occur between multiple render calls. When a call is made to hdrcRenderQueue.render() or hdrcRenderQueue.setRenderParams(), the most recently specified RENDER_PARAMS will be used if the rendering server is idle. However, if the rendering server is in the process of rendering a frame, the call to hdrcRenderQueue.render() will be ignored, and calls to hdrcRenderQueue.setRenderParams() will queue a new set of RENDER_PARAMS, but no new frame will be generated.

 

Any call to hdrcRenderQueue.setRenderParams() will trigger an implicit render(). Note that invoking hdrcRenderQueue.render() will not impact performance or cause unnecessary rendering.

 

Consider the following code example. In this example a set of RENDER_PARAMS is set and a new render pass begins automatically. Then a second set of RENDER_PARAMS is sent. Because the render engine is already rendering the first set of RENDER_PARAMS, the new RENDER_PARAMS are queued up for the next server rendering pass, but no new frame is actually generated. In this case the client will not receive an image with the second set of RENDER_PARAMS. The client application must wait until the rendering server has completed the first frame before it can begin to render another frame with the new RENDER_PARAMS set. To check the status of the rendering server a call can be made to hdrcRenderQueue.isRendering().

 

// Set RENDER_PARAMS set 1.

renderQueue.setRenderParams(rp1);

 

// Set RENDER_PARAMS set 2.

renderQueue.setRenderParams(rp2);