Renders to an off-screen buffer for printing or generating textures. More...
#include <Inventor/SoOffscreenRenderer.h>
Renders to an off-screen buffer for printing or generating textures.
This class is used to render into an off-screen buffer to create a printable image or to generate a texture image. It uses a Pbuffer (if possible) or an off-screen bitmap for rendering. Methods are provided to write the buffer to a file, as an RGB image, an encapsulated PostScript description, or in one of several other image formats.
NOTE: This class does not exist in Open Inventor 10.0 and later. Replace with SoOffscreenRenderArea.The renderer can generate images of any size. If the requested image size exceeds OpenGL rendering capabilities, the image will be created by automatically rendering some number of "tiles" and "stitching" them together. See setMaxTileSize for details. Using tiles allows you to create very large, very high resolution images. For example, a poster size image to be printed at 300 dpi would need to be (approximately) 10,000 pixels wide.
The renderer can generate images with a transparent background (as long as there is an OpenGL render format available that supports an alpha buffer). See setBackgroundColorRGBA(). Note that you must also call setComponents() with the parameter set to RGBA (setBackgroundColorRGBA does not do this automatically).
Some output file formats are much more efficient than others at dealing with tiled output. If you anticipate generating very large images, it may be helpful to chose an output format that can generate tiled output efficiently. The formats in the "WRITE_SCANLINES" column in the following table are more efficient at generating tiled output.
Write Capability WRITE_FULL_IMAGE | Write Capability WRITE SCANLINES |
BMP JP2 (JPEG2000) PGX PNM PNG SUN TIFF | JPEG PS (PostScript) SGIRGB |
For the WRITE_FULL_IMAGE formats, the entire image must be written at once, so a buffer large enough for the whole image is allocated, and tiles are copied into it. Therefore it must be possible to allocate enough memory for a single tile (num_components * tile_width * tile_height) plus enough memory to assemble the complete image (num_components * width * height).
For the WRITE_SCANLINES formats, the image can be written incrementally, some number of scanlines at a time. Therefore it is only necessary to allocate enough memory for a single tile, which at most will be the size of the maximum OpenGL viewport (typically 2048x2048).
See the documentation for SoRasterImageRW and the individual image classes (SoBMPImageRW, SoGIFImageRW, etc.) for further information.
PBuffers
Beginning with Open Inventor 3.1, this class will automatically try to use an OpenGL Pbuffer for rendering. If a Pbuffer is available, rendering will be accelerated by the 3D graphics hardware. If no Pbuffer is available, rendering will use a software rendered off-screen buffer as before. Pbuffers are a standard feature of OpenGL 1.2 and are often available as an extension on older versions of OpenGL. However it is not guaranteed that Pbuffers will be available or that a Pbuffer of the desired size can be created.
Rendering with a Pbuffer will generally produce the same image as would be rendered on the screen, but this is not guaranteed. In general, software rendering will produce the same image as on-screen if only OpenGL 1.1 features are used. Newer OpenGL features and extensions will generally not be available using software rendering.
Note that Pbuffers are a limited resource. If the application creates multiple instances of SoOffscreenRenderer, it may be desirable to prevent some of them (that are lower priority or render small scene graphs) from using a Pbuffer. See the method setPbufferEnable().
Rendering contexts
The setShareContext method allows you to share an already existing OpenGL context with the offscreen renderer. This avoids the necessity to re-generate textures and display lists if they are already available in another OpenGL context (the viewer context, for instance). This can dramatically reduce offscreen rendering time, depending on your scene graph.
A corresponding query method (getShareContext) is also available.
Here's how you might use these methods to share OpenGL contexts:
renderer->setShareContext( pViewer->getShareContext() );
Rendering a "snapshot"
SoOffscreenRenderer is often used to save a snapshot of the image in the viewer window. There are several common pitfalls. First, the scene graph given to the renderer must include the camera node that the viewer is using. If the application allows the viewer to create a camera automatically, the scene graph returned by the viewer's getSceneGraph() method does not include the camera. It's always safer to get the SoSceneManager object then get the scene graph. Second, some rendering options are set on the viewer object, not in the scene graph. These options, which include background color and transparency mode, must be explicitly queried from the viewer and set on the renderer object.
Sample code to make a snapshot, given a viewer object, might look like this:
// Make image same size and shape as viewer image SoOffscreenRenderer renderer( pViewer->getViewportRegion() ); // Transfer viewer settings to renderer renderer.setShareContext( pViewer->getShareContext() ); renderer.setBackgroundColor( pViewer->getBackgroundColor() ); renderer.getGLRenderAction()->setTransparencyType( pViewer->getTransparencyType() ); // Render scene (including camera and headlight) renderer.render( pViewer->getSceneManager()->getSceneGraph() ); // Write image to a file in PNG format renderer.writeToPNG( "output.png" );
See: $OIVHOME/examples/source/Inventor/examples/Mentor/Cxx/09.1.Print.cxx for a complete example.
NOTE: Tiled rendering does not currently work correctly when a camera node's viewportMapping field is set to one of the CROP_ options. It does work correctly with the LEAVE_ALONE and ADJUST_CAMERA (default) settings.
SoOffscreenRenderer is useful because it allows the image size to be specified (e.g. different than the on-screen window) and because it can render images of almost any size (much larger than the physical screen). However it does require an additional render traversal to create the image. For a simple snapshot of an on-screen window it may be more efficient to use the saveSnapshot() method in the So___GLWidget class (e.g. SoWinGLWidget).
SoRasterImageRW, SoWinGLWidget::saveSnapshot(), SoQtGLWidget::saveSnapshot(), SoXtGLWidget::saveSnapshot(), SoWxGLWidget::saveSnapshot()
typedef AbortCode SoOffscreenRenderer::SoOffscreenAbortCB(void *userData, int numSubimage, int subimageCount) |
Callback functions for render abort should be of this type.
This typedef is defined within the class, since it needs to refer to the AbortCode enumerated type.
SoOffscreenRenderer::SoOffscreenRenderer | ( | const SbViewportRegion & | viewportRegion | ) |
Constructor.
An internal instance of an SoGLRenderAction will be maintained with a viewport region set to the one passed in by the constructor.
SoOffscreenRenderer::SoOffscreenRenderer | ( | SoGLRenderAction * | ra | ) |
Constructor.
The render action passed to the constructor will be used in all subsequent offscreen renderings.
SoOffscreenRenderer::~SoOffscreenRenderer | ( | ) |
Destructor.
const SbColor& SoOffscreenRenderer::getBackgroundColor | ( | ) | const [inline] |
Returns the background color for rendering.
const SbColorRGBA& SoOffscreenRenderer::getBackgroundColorRGBA | ( | ) | const [inline] |
Returns the RGBA background color for rendering.
unsigned char* SoOffscreenRenderer::getBuffer | ( | BufferType | buffType = SoOffscreenRenderer::RGB_BUFFER |
) |
Returns a buffer containing the rendered image.
This memory is "owned" by Open Inventor and should not be deleted by the application. The memory is freed when the SoOffscreenRenderer object is destroyed.
If the specified buffer type is RGB_BUFFER, the buffer is an array of bytes (unsigned char) . Each pixel is stored sequentially by scanline, starting with the lower left corner. The data stored for each pixel is determined by the Components set before rendering. Pixels are stored in RGBA order and are packed without any padding between pixels or scanlines.
If the specified buffer type is JPEG_BUFFER and writeToJPEG has been called with a NULL file descriptor, the buffer contains the result of the requested JPEG encoding (see writeToJPEG quality argument). The returned buffer is available until the destructor is called or writeToJPEG(JPEG_BUFFER) is called again.
The buffer size is returned by the getBufferSize method.
size_t SoOffscreenRenderer::getBufferSize | ( | BufferType | buffType = SoOffscreenRenderer::RGB_BUFFER |
) |
Returns the buffer size in bytes.
If the specified buffer type is JPEG_BUFFER, getBufferSize returns 0 if writeToJPEG (JPEG_BUFFER) has not been called yet.
int SoOffscreenRenderer::getColorDepth | ( | ) | const [inline] |
Gets the color depth to be used for offscreen rendering.
Components SoOffscreenRenderer::getComponents | ( | ) | const [inline] |
Returns the components to be rendered.
const HDC& SoOffscreenRenderer::getDC | ( | ) | const |
[Windows only] This method has no effect on UNIX systems.
Returns the "device context" containing the rendered image.
This value is only valid after the "render" method has been called (at least once) on an instance of SoOffscreenRenderer. Standard Win32 API calls can be used to retrieve the actual bitmap (DIBsection) from this device context, to copy the bitmap into another device context, and so on. Not useful if tiled rendering was required.
SoGraphicConfigTemplate::Preference SoOffscreenRenderer::getFullSceneAntialiasing | ( | int & | minFsaaBits, | |
int & | maxFsaaBits | |||
) | const |
Returns the full-scene antialiasing preference and number of samples.
SoGLRenderAction* SoOffscreenRenderer::getGLRenderAction | ( | ) | const |
Gets the render action to use for rendering.
This will return any render action passed in by the caller.
SoGLGraphicConfigTemplate* SoOffscreenRenderer::getGraphicConfigTemplate | ( | ) |
Gets the current graphics configuration template.
static SbVec2s SoOffscreenRenderer::getMaximumResolution | ( | ) | [static] |
Gets the maximum supported resolution of the viewport.
SbVec2s SoOffscreenRenderer::getMaxSubimage | ( | ) | const [inline] |
Synonym for getMaxTileSize.
SbVec2s SoOffscreenRenderer::getMaxTileSize | ( | ) | const [inline] |
Gets the maximum subimage (tile) size for rendering.
int SoOffscreenRenderer::getNumEdgePixels | ( | ) | const [inline] |
Gets the number of pixels on the edge of each subimage that are not written on the big image (overlapped pixels).
SbBool SoOffscreenRenderer::getPbufferEnable | ( | ) | const [inline] |
Returns TRUE if a Pbuffer may be used for rendering.
static float SoOffscreenRenderer::getScreenPixelsPerInch | ( | ) | [static] |
Returns the number of pixels per inch (in the horizontal direction) of the current X device screen.
const SbGLShareContext SoOffscreenRenderer::getShareContext | ( | ) | const |
Gets the OpenGL context shared by the SoOffscreenRenderer.
const SbViewportRegion& SoOffscreenRenderer::getViewportRegion | ( | ) | const |
Returns the viewport region used for rendering.
SbBool SoOffscreenRenderer::isFullSceneAntialiasing | ( | float & | quality | ) |
Returns TRUE if FSAA is currently enabled.
Also returns the current quality value.
Renders the given scene, specified as a path, into an off-screen buffer.
Note: If tiled rendering will be done, the application must call render(), but the actual rendering is not done until one of the writeToXXX() methods or getBuffer() is called.
Renders the given scene, specified as a node, into an off-screen buffer.
Note: If tiled rendering will be done, the application must call render(), but the actual rendering is not done until one of the writeToXXX() methods or getBuffer() is called.
void SoOffscreenRenderer::setAbortCallback | ( | SoOffscreenAbortCB * | func, | |
void * | userData | |||
) | [inline] |
Sets callback to call during rendering to test for abort condition.
It will be called for each subimage (tile) that is rendered. This allows the application to terminate rendering prematurely if some condition occurs. The callback function should return one of the AbortCode values to indicate whether rendering should continue.
Rendering a big image can take a long time (in the user's perception anyway). This callback can also be used to display a "progress bar" or other indication of how much work has been completed. numSubImage gives the total number of subimages to be rendered. subImageCount gives the number of subimages rendered so far.
void SoOffscreenRenderer::setBackgroundColor | ( | const SbColor & | c | ) |
Sets the RGB background color for rendering.
The default is (0,0,0) = opaque black. The default value can be set using the environment variable OIV_BACKGROUND_COLOR. Specify three floats (R, G, B) in the range 0. to 1., separated by spaces. See also setBackgroundColorRGBA().
void SoOffscreenRenderer::setBackgroundColorRGBA | ( | const SbColorRGBA & | c | ) |
Sets the RGBA background color for rendering.
The default is (0,0,0,1) = opaque black. The default RGB color (but NOT alpha) can be set using the environment variable OIV_BACKGROUND_COLOR. See also setBackgroundColor().
Notes:
void SoOffscreenRenderer::setColorDepth | ( | int | nbits | ) |
Sets the color depth to be used for offscreen rendering.
Currently the only values allowed are 8 and 24 (the default is 24). This feature is useful if you want to do 256 color dithered rendering for printing. The change does not take effect until the next render() or setupPixmap () call.
Note: WriteToBMP does not currently support 256 color bitmaps.
void SoOffscreenRenderer::setComponents | ( | Components | components | ) |
Sets the components to be rendered.
Default is RGB. Alpha values will not be available if OpenGL does not provide any pixel formats with an alpha buffer. Some image file formats, for example JPEG, do not support alpha values. If you write to one of these formats only the RGB components will be saved.
void SoOffscreenRenderer::setFullSceneAntialiasing | ( | SbBool | enable, | |
float | quality = -1.0 , |
|||
int | filterMask = SoFullSceneAntialiasing::ALL | |||
) |
Sets the full-scene antialiasing preferences.
Note: Use the SoFullSceneAntialiasing node to control FSAA during render traversal.
enable | Enables or disables FSAA rendering. | |
quality | Specifies the level of quality of the antialiasing rendering. The number of samples used in the antialiasing computation depends on your graphics hardware and on your video driver. NVidia graphics hardware can support number of samples * 2 levels of quality (assuming the NV_multisample_filter_hint OpenGL extension is available). The quality value is in the [0..1] interval. 0 is the lowest quality level and 1 is the highest quality level. When set to -1.0 the quality value is the default value for the pixel format. | |
filterMask | Specifies the types of shapes that should be antialiased (See SoFullSceneAntialiasing for more info.) |
void SoOffscreenRenderer::setFullSceneAntialiasing | ( | SoGraphicConfigTemplate::Preference | pref, | |
int | minFsaaBits = 0 , |
|||
int | maxFsaaBits = INT_MAX | |||
) |
Sets the full-scene antialiasing preferences.
minBits and maxBits are the minimum and maximum required number of samples used during antialiasing computation. The required number of samples must be greater than or equal to minBits, and less than or equal to maxBits. The maximum number of samples is always preferred. If pref is FORBIDDEN, the min/max values are ignored.
void SoOffscreenRenderer::setGLRenderAction | ( | SoGLRenderAction * | ra | ) |
Sets the render action to use for rendering.
void SoOffscreenRenderer::setGraphicConfigTemplate | ( | SoGLGraphicConfigTemplate * | gTemplate | ) |
Sets a new graphics configuration template.
void SoOffscreenRenderer::setMaxSubimage | ( | SbVec2s | size | ) |
Synonym for setMaxTileSize.
void SoOffscreenRenderer::setMaxTileSize | ( | SbVec2s | size | ) |
Sets the maximum subimage (tile) size for rendering.
The default value is 1984 by 1984. This corresponds to the typical maximum image that OpenGL can render, 2048 by 2048 on low end GPU, minus a 32-pixel overlap on each edge.
The maximum tile size that is set should not exceed the maximum image size that OpenGL can render (implementation and/or hardware dependent) minus two times the number of edge pixels (see below).
Note that GPU memory consumption of some nodes, like SoVolumeRender, depends on viewport size because they need to allocate Frame buffer objects. If you experiment over GPU memory consumption, try to decrease the MaxTileSize.
void SoOffscreenRenderer::setNumEdgePixels | ( | int | nb | ) |
Sets the number of pixels on the edge of each subimage that are not written on the big image (overlapped pixels).
The default value is two pixels. Some overlap is usually required to avoid visual "artifacts" at the subimage boundaries. One source of artifacts is that when OpenGL clips lines, it draws a line between the points where the line exits and re-enters the visible region. This additional segment is not part of the actual geometry. A two pixel overlap will hide this undesired segment unless the line width is greater than two, in which case you may need to specify a larger overlap.
void SoOffscreenRenderer::setPbufferEnable | ( | SbBool | enable | ) |
Specifies if a Pbuffer may be used for rendering.
Pbuffers are a limited resource. If an application is using multiple offscreen renderers, it may better to use normal pixmap rendering for some of them. Must be called before the first call to render(). Default is TRUE.
Sets a subregion of the viewport to be rendered.
Units are pixels. For regions greater thatn 32767, use the setRegion_i32 method. The origin is relative to the lower left corner. Only this region will be rendered, returned by getBuffer, or written to a file.
Sets a subregion of the viewport to be rendered.
Units are pixels. The origin is relative to the lower left corner. Only this region will be rendered, returned by getBuffer, or written to a file.
void SoOffscreenRenderer::setShareContext | ( | const SbGLShareContext | shareCxt | ) |
Sets the OpenGL context to be shared by the SoOffscreenRenderer.
Its use is strongly recommended, because it can improve performance when switching between on-screen and off-screen rendering. This is because it allows the display lists and texture objects to be shared between the on-screen and off-screen render context. The shared context info is normally obtained by calling the viewer's getShareContext method.
NOTE: It has no effect when the hardware (or driver) does not allow sharing with the off-screen context, for example if Pbuffers are not supported.
void SoOffscreenRenderer::setTileObserver | ( | SoOffscreenTileObserver * | tileObserver | ) |
Specifies a tile observer object which will be called after each tile is rendered.
void SoOffscreenRenderer::setViewportRegion | ( | const SbViewportRegion & | region | ) |
Sets the viewport region used for rendering.
This will NOT be applied to the viewport region of any render action passed in.
[Windows only] This method has no effect on UNIX systems.
Writes the buffer as a "Windows RGB Encoded" .bmp file to the given filename. Since Open Inventor 9.0
SbBool SoOffscreenRenderer::writeToBMP | ( | FILE * | fp | ) | const |
[Windows only] This method has no effect on UNIX systems.
Writes the buffer as a "Windows RGB Encoded" .bmp file to the given file pointer.
Writes the buffer as a JPEG file to the given filename.
If the given file does not exist or cannot be opened, the JPEG compression stream is written to a buffer. Previous JPEG buffers are deleted and a new one is created. The getBuffer method returns this buffer, and getBufferSize returns this buffer size.
filename | the filename to save the result to. | |
quality | Specifies the quality of the compression. 1.0 is the best quality with the least compression. 0.0 is the worst quality with the most compression. A typical value for quality is 0.7. |
SbBool SoOffscreenRenderer::writeToJPEG | ( | FILE * | fp, | |
float | quality = 1.0 | |||
) | const |
Writes the buffer as a JPEG file to the given file pointer.
If the file pointer is NULL, the JPEG compression stream is written to a buffer. Previous JPEG buffers are deleted and a new one is created. The getBuffer method returns a pointer to the buffer, and getBufferSize returns the buffer size.
1.0 is the best quality with the least compression, 0.0 is the worst quality with the most compression. A typical value for quality is 0.7.
Writes the buffer as a PNG file to the given filename. Since Open Inventor 9.0
SbBool SoOffscreenRenderer::writeToPNG | ( | FILE * | fp | ) | const |
Writes the buffer as a PNG file to the given file pointer.
The file must be opened in binary mode.
SbBool SoOffscreenRenderer::writeToPostScript | ( | const SbString & | filename, | |
const SbVec2f & | printSize | |||
) | const |
Writes the buffer as encapsulated PostScript to the given filename.
The print size is specified in inches. Since Open Inventor 9.0
Writes the buffer as encapsulated PostScript to the given file pointer.
The print size is specified in inches.
Writes the buffer as encapsulated PostScript to the given filename.
The size of the image in the buffer is adjusted so it is the same as the apparent size of the viewport region on the current device. Since Open Inventor 9.0
SbBool SoOffscreenRenderer::writeToPostScript | ( | FILE * | fp | ) | const |
Writes the buffer as encapsulated PostScript to the given file pointer.
The size of the image in the buffer is adjusted so it is the same as the apparent size of the viewport region on the current device.
SbBool SoOffscreenRenderer::writeToRaster | ( | const SbString & | filename, | |
SoRasterImageRW * | imageWriter | |||
) |
Writes the buffer using the image writer class passed as the second parameter.
This is a general interface for writing the image buffer to a file. All the file format-specific writeTo methods actually call this method. See classes SoXXXImageRW (e.g., SoBMPImageRW, etc.). Since Open Inventor 9.0
SbBool SoOffscreenRenderer::writeToRaster | ( | FILE * | fp, | |
SoRasterImageRW * | imageWriter | |||
) |
Writes the buffer using the image writer class passed as the second parameter.
This is a general interface for writing the image buffer to a file. All the file format-specific writeTo methods actually call this method. See classes SoXXXImageRW (e.g., SoBMPImageRW, etc.).
Writes the buffer as an .rgb file to the given filename. Since Open Inventor 9.0
SbBool SoOffscreenRenderer::writeToRGB | ( | FILE * | fp | ) | const |
Writes the buffer as an .rgb file to the given file pointer.
SbBool SoOffscreenRenderer::writeToTIFF | ( | const SbString & | filename, | |
TIFFCompressionMode | TIFFcm = PACKBITS_COMPRESSION | |||
) | const |
Writes the buffer as a TIFF file to the given filename. Since Open Inventor 9.0
SbBool SoOffscreenRenderer::writeToTIFF | ( | FILE * | fp, | |
TIFFCompressionMode | TIFFcm = PACKBITS_COMPRESSION | |||
) | const |
Writes the buffer as a TIFF file to the given file pointer.