Open Inventor FAQs - Textures

How come my texture appears to "warp" on the surface of my objects (when I use a perspective camera)?

What you are seeing is a common visual result, and has an easy cure. At the top of your scene graph, insert an SoComplexity node and set the value of its textureQuality field to at least 0.6.

(The default textureQuality is 0.5 for best performance. However, the visual results may not be acceptable for all situations.)

Here's some sample additional code:

SoComplexity *complexity = new SoComplexity;
ro ot->addChild(complexity);

SoTexture2 *texture = new SoTexture2;
root->addChild(texture); texture->filename.setValue("texturefile.rgb");

Here's the equivalent info as it might appear in an Inventor file:

Complexity { 
  textureQuality 0.6

Texture2 { filename "texturefile.rgb"

Here are "before" and "after" pictures showing textureQuality 0.5 and 1.0:


[Win32] I'm getting a stack overflow error when I attempt to display a scene graph with a large texture. What should I do?

This can occur if you have a large texture image which does not have "power of 2" dimensions. OpenGL requires that texture images have dimensions which are a "power of 2", for example 64, 128, 256, etc. If your texture image does not meet this requirement, Open Inventor will automatically scale it up to the closest power of 2 value, using gluScaleImage. However Open Inventor allocates memory for the larger image on the "stack" and Windows NT has a default stack size limit of 1 MB. If the image size exceeds the stack size limit, the program will crash.

You can avoid this problem by only providing texture images with "power of 2" dimensions. This is also much more efficient because Open Inventor does not need to allocate memory and scale the image before drawing.

You can also avoid this problem by increasing the stack size limit. There are several ways to do this including:

  • Add a /STACK:numbytes option to the linker command line.
  • In VC++, open the Build/Settings dialog, select the Link tab, select "Output" from the Categories pulldown, enter the desired value in the Stack allocations "Reserve" text field. 2MB might be a good value depending on the size of the texture.
  • Use "EDITBIN /STACK:numbytes program.exe" to modify the executable file's header. (This method could be used on the prebuilt SceneViewer if you need to read in a model with a very large texture.)

How does Open Inventor texture quality relate to OpenGL texture mapping options?

Here is a table and some notes.

Value for min filter and need_mipmaps
Texture Quality Min Filter Value Need Mimaps
 // Value for mag filter
magFilter = (quality < 0.75 ? GL_NEAREST : GL_LINEAR);


  • While it is literally true that no value of TextureQuality corresponds to GL_LINEAR for both min and mag filters, this is not usually a problem in practice since, in most cases, the value for the minification filter is the important one.
  • On most machines the default TextureQuality is 0.5, causing GL_NEAREST to be used. This gives the best performance with software rendering, but often causes unacceptable aliasing effects (visible as "distortion" of the texture image).
  • 0.6 is a good, general purpose, value for TextureQuality that has reasonable performance even with software rendering and reasonable appearance. It uses GL_LINEAR for the min filter. This is sometimes called bi-linear interpolation because it interpolates the texel values in two directions within the image.
  • 0.8 is generally a good value for higher performance boards with mipmap support. GL_NEAREST_MIPMAP_LINEAR chooses the nearest mipmap level and does GL_LINEAR interpolation within that level. Note that Inventor generates the mipmap levels automatically if required by the TextureQuality setting.

Is there a limit for the texture size for Open Inventor?

No, there's no limit in Open Inventor but there is a limit in OpenGL -- which is implementation dependent. Query it with glGetInteger using the parameter name GL_MAX_TEXTURE_SIZE. The value gives a rough estimate of the largest texture that the GL can handle. If the GL version is 1.1 or greater, use GL_PROXY_TEXTURE_1D or GL_PROXY_TEXTURE_2D to determine if a texture is too large. See glTexImage1D and glTexImage2D.

The application I have uses many scene graphs stored in .wrl files with externally defined textures (i.e. textures are stored in .jpg files and loaded by the .wrl file). Since many of the same textures are used by different input VRML files, is Open Inventor smart enough to load the texture only once and use it for all VRML files, or does it load the texture file multiple times?

Currently the only time Open Inventor "shares" a texture image is when the same texture node is referenced multiple times. In other words, if you create two texture nodes and set the "filename" field to the same filename in both, they will each load that image file, so the file will be loaded twice. This is because creating two distinct texture nodes tells Inventor that they are somehow two different objects to your application -- for example the app might be planning to change the image in one of the nodes programmatically (but not in the other), so Inventor has to keep them separate.

FYI, when IVF (Win32 only) (but not core Inventor) loads an Inventor file, one of the (optional) optimizations it performs is to find all the texture nodes, compare their filename fields and replace "duplicate" texture nodes with a reference to a single texture node that loads that particular filename.

Texture image not shared:

SoTexture2 *pTex1 = new SoTexture2;
SoTexture2 *pTex2 = new SoTexture2;

pTex1->filename = "myImage.gif";
pTex2->file name = "myImage.gif";

pSep1->addChild( pTex1 );
pSep2->addChild( pTex2 );

Texture image is shared (only loaded once):

SoTexture2 *pTex1 = new SoTexture2;
pTex1->filename = "myImage.gif";
pSep1->addChild( pTex1 );
pSep2->addChild( pTex1 );

It seems to take a long time to display my scene graph that uses a lot of texture images.

This might just be a "fact of life" for your system, or there may be things you can do to improve the situation.

Use power-of-2 texture dimensions

As you may know, OpenGL only handles textures that have dimensions that are powers of 2. If you provide texture images that have dimensions that are not powers of two, Open Inventor will automatically scale them up to the nearest power of 2. This is a convenience feature, but can be time consuming because of the computations that are involved. We recommend that users provide textures that are already dimensioned in powers of 2 in order to improve performance. However, note that scaling is only done once, so this does not affect overall frame rate, only the time to display the initial image.

If you are particularly concerned about keeping the image quality as high as possible, don't scale the image, but rather add (any color) pixels to the top and right to make the image size a power of 2. Then use texture coordinates to tell Open Inventor to use only the portion of the image that contains the "real" texture pixels.

For example:

  1. Suppose your image is 400 x 400.
  2. Add 112 pixels (of any color) on the top and right to make an image that is 512 x 512.
  3. When you map this texture to your object, specify texture coordinates such that only the pixels from 1-400 are mapped onto your object. For a rectangular polygon, the texture coordinates, starting at the lower left, counterclockwise, would be (0,0), (.78125,0), (.78125,.78125), (0,.78125).

This produces better quality because there is one less scale operation to potentially cause a loss of quality.

Use SoExtTexture2 Node

This new node (available in OIV 3.0 and up) was specifically designed for handling texture memory and system memory efficiently.

  • It doesn't load the texture image into system memory until the node is traversed. Depending on the scene graph, this may significantly reduce the use of system memory, e.g., if the scene has lots of LODs containing textures. The textures will only be loaded for nodes that are actually displayed (i.e., only the active LOD children). On the other hand, when the scene graph is first traversed there may be a small delay while the textures are being loaded.
  • To reduce the use of texture memory (by approximately a factor of 4), use the useTexturePalette method to request the image be converted to a 256-color paletted image. This feature is available only if the driver supports the GL_EXT_paletted_texture or GL_EXT_texture_color_table extension.

See the SoExtTexture2 write-up in the help file for further details.

How can I texture map an RGBA image onto a polygon such that the unwanted part of the image is transparent?

The following strategy will work:

  • Set the SoTexture2 model field to MODULATE (default). (This controls how the alpha values of the texture affect the geometry.)
  • For the portion of the texture to be invisible (i.e. fully transparent), the alpha value should be zero. Note: Some image file formats do not support alpha values.
  • For the portion of the texture to be visible (i.e. fully opaque), the alpha value should be the maximum (typically 255 for a 4-byte RGBA image).
  • Call the method setTransparencyType (see SoWinRenderArea) to set any of the blended transparency types. (Transparent textures only appear transparent if they are blended with the existing pixels in the frame buffer. Screen door transparency (the default) won't work.)

Tip: On some systems, you may get better performance selecting a textureQuality of 1.0.

While it may seem odd, using a higher texture quality can sometimes improve performance.

On some systems, specifing a texture quality of 1.0 (SoComplexity::textureQuality) may provide better performance than the default texture quality (0.5). For example, we have seen this on Windows, with a GeForce Quadro2 MXR/EX.