13.1. Generating an image

To print all or part of an Inventor scene graph, use theSoOffscreenRenderArea( C++ | Java | .NET ) class, which in turn uses an SoGLRenderAction( C++ | Java | .NET ) to render an image into an off-screen memory buffer. This rendering buffer can be used both to generate an image to send to a PostScript printer and to generate an image to be used as a texture map.

To write a scene graph to a file in Encapsulated PostScript (EPS) format, you first render the scene with the off-screen renderer. Then you use the writeToPostScript() method to generate the PostScript output and write it to the given file.

For example, suppose you want to print a screen area that is 300 pixels by 400 pixels. Use the setWindowSize() method on SbViewportRegion( C++ | Java ) to specify the size of the viewport to be printed:


C++
SbViewportRegion vp;
vp.setWindowSize(SbVec2s(300, 400));

rootNode = getMyScene();

SoOffscreenRenderArea renderer() = new SoOffscreenRenderArea();
renderer->setViewportRegion(vp);
renderer->setSceneGraph(rootNode);
renderer->renderToFile("fileName.ps");
              

.NET
SbViewportRegion vp = new SbViewportRegion();
vp.SetWindowSize(new SbVec2s(300, 400));

SoOffscreenRenderArea renderer = new SoOffscreenRenderArea();
renderer.SetViewPortRegion(vp);
renderer.SetSceneGraph(rootNode);
renderer.RenderToFile("fileName.ps");
         

Java
SbViewportRegion vp = new SbViewportRegion();
vp.setWindowSize(new SbVec2s((short)300, (short)400));

SoOffscreenRenderArea renderer = new SoOffscreenRenderArea();
renderer.setViewPortRegion(vp);
renderer.setSceneGraph(rootNode);
renderer.renderToFile("fileName.ps");
         

This code fragment assumes the default pixels per inch (approximately 72). To change the number of pixels per inch, use the setPixelsPerInch() method on SbViewportRegion( C++ | Java ). Typically, you use the resolution of the printer. For a 300 dots-per-inch (DPI) printer, you would specify the following:


C++
vp.setPixelsPerInch(300);
              

.NET
vp.SetPixelsPerInch(300);
         

Java
vp.setPixelsPerInch(300);

This resolution affects line width, the size of 2D text, and point size, which are all specified in pixels.

You may want the printed image to be the same size as the image rendered on the screen. To determine the size of the image on the screen, first use the getViewportSizePixels() method on SbViewportRegion( C++ | Java ) to obtain the number of pixels (in x and y) of the viewport region.


C++
screenVp = renderArea->getViewportRegion();
SbVec2s screenSize = screenVp.getViewportSizePixels();
float screenPixelsPerInch = SoGLScreenDevice::getPhysicalSize() / SoGLScreenDevice::getResolution()
              

.NET
screenVp = renderArea.GetViewportRegion();
SbVec2s screenSize = screenVp.ViewportSizePixels;
float screenPixelsPerInch = SoGLScreenDevice::getPhysicalSize() / SoGLScreenDevice::getResolution()
         

Java
screenVp = renderArea.getViewportRegion();
SbVec2s screenSize = screenVp.getViewportSizePixels();
float screenPixelsPerInch = SoGLScreenDevice::getPhysicalSize() / SoGLScreenDevice::getResolution()

Now you can calculate the size of the screen image in pixels by dividing x and y by screenPixelsPerInch. If you have a 300-by-400-pixel viewport on a screen with a resolution of 100 pixels per inch, your image is 3 by 4 inches.

To print this image at the same size, you specify the following:


C++
vp.setWindowSize(SbVec2s(x_in_inches * printer_DPI, y_in_inches * printer_DPI));

vp.setPixelsPerInch(printer_DPI);
              

.NET
vp.SetWindowSize(new SbVec2s(x_in_inches * printer_DPI, y_in_inches * printer_DPI));

vp.SetPixelsPerInch(printer_DPI);
         

Java
vp.setWindowSize(new SbVec2s((short)(x_in_inches * printer_DPI),
                             (short)(y_in_inches * printer_DPI)));

vp.setPixelsPerInch(printer_DPI);

Your OpenGL implementation may restrict the maximum viewport size. Use getMaximumResolution() to obtain the maximum resolution possible for a viewport in your window system. Example named OffscreenRendering shows simple functions that render a given scene graph and then saves it in a file that can be sent to a printer.

You can also use the off-screen renderer to render an image to be used as a texture map. In this case, use the renderToBuffer() method of SoOffscreenRenderArea to render the image. Example named 09.2.Texture shows how to generate a texture using the SoOffscreenRenderArea( C++ | Java | .NET ) class.