Class for 2D indexed texture. More...
#include <Inventor/nodes/SoIndexedTexture2.h>
Public Member Functions | |
virtual SoType | getTypeId () const |
void | computeDataRange () |
SoIndexedTexture2 () | |
Static Public Member Functions | |
static SoType | getClassTypeId () |
Public Attributes | |
SoSFFloat | minValue |
SoSFFloat | maxValue |
SoSFArray2D | imageIndex |
SoSFBool | rescaleTexCoord |
SoSFEnum | wrapT |
This property node defines an "indexed" texture image. In a standard texture image, e.g. SoTexture2, each texel contains a color value that is directly applied to the geometry. In this node each texel contains a data value that is mapped to a color value using the color map defined by the current SoColorMap node.
This image is stored in the current texture unit (see SoTextureUnit) and the texture is applied to subsequent shapes as they are rendered.
The image data is stored in an SoSFArray2D. This array can contain different types of data (UNSIGNED_BYTE, UNSIGNED_SHORT, UNSIGNED_INT32, SIGNED_BYTE, SIGNED_SHORT, SIGNED_INT32, FLOAT).
When Open Inventor creates the OpenGL texture image from the data array, the data values must be scaled into the range of values of the texture (0-255 for an 8-bit indexed texture). The minValue and maxValue fields specify the range of data values that will be scaled into the range of texture values. For example, if minValue is set to 10000 and maxValue to 38000, all values less than or equal to 10000 will be mapped to the entry 0 of the color map and all values greater than or equal to 38000 to the last entry. The image below illustrates the process of mapping and shows how it can be used to map only the used data range to the color map:
If minValue or maxValue change, then the OpenGL texture must be recreated. If the texture is large, this may be time consuming. Generally it's more efficient to modify the SoColorMap node because the OpenGL texture corresponding to the data does not need to be recreated -- only the texture containing the colormap, which is normally quite small.
NOTE: Texture data values are stored with 12 bits of precision instead of the usual 8 bits, when:
SoColorMap *colorMap = new SoColorMap(); colorMap->predefinedColorMap = SoColorMap::TEMPERATURE; colorMap->min.setValue( -1000 ); colorMap->max.setValue( 20000 ); SoIndexedTexture2 *indexedTexture = new SoIndexedTexture2(); indexedTexture->imageIndex.setValue(size, SoSFArray2D::SIGNED_SHORT, data); root->addChild( colorMap ); root->addChild( indexedTexture ); root->addChild( geometry );
// Fragment shader uniform sampler2D colormap; uniform sampler2D indexedTex1; uniform sampler2D indexedTex2; void main() { // Fetch first value and its assigned color float value1 = texture(indexedTex1, gl_TexCoord[0].xy).x; vec4 color1 = texture(colormap, vec2(value1, 0)); // Fetch second and its assigned color float value2 = texture(indexedTex2, gl_TexCoord[0].xy).x; vec4 color2 = texture(colormap, vec2(value2, 0)); // Combine the colors gl_FragColor = color1 * color2 * gl_Color; }
The scene graph would be initialized like this:
SoColorMap* colorMap = new SoColorMap(); . . . SoIndexedTexture2* indexedTex1 = new SoIndexedTexture2(); . . . SoIndexedTexture2* indexedTex2 = new SoIndexedTexture2(); . . . SoFragmentShader* fragShader = new SoFragmentShader(); fragShader->sourceProgram = "filename.glsl"; fragShader->addShaderParameter1i( "colorMap" , 0 ); fragShader->addShaderParameter1i( "indexedTex1", 1 ); fragShader->addShaderParameter1i( "indexedTex2", 2 ); SoShaderProgram* shaderProgram = new SoShaderProgram(); shaderProgram->shaderObject = fragShader; SoTextureUnit* textureUnit = new SoTextureUnit(); textureUnit->unit = 2; //Texture unit for the second indexed texture root->addChild(colorMap); //Color map must come first (texture unit 1) root->addChild(indexedTex1); //First indexed texture (texture unit 0) root->addChild(textureUnit); root->addChild(indexedTex2); //Second indexed texture (texture unit 2) root->addChild(shaderProgram); root->addChild(geometry);
minValue | 0 |
maxValue | 0 |
imageIndex | 0 0 |
rescaleTexCoord | FALSE |
wrapS | REPEAT |
wrapT | REPEAT |
model | MODULATE |
blendColor | 0 0 0 |
enableBorder | FALSE |
borderColor | 0 0 0 0 |
maxAnisotropy | 1.0 |
minFilter | AUTO |
magFilter | AUTO |
useAutoMipmap | FALSE |
internalFormat | AUTO_INTERNAL_FORMAT |
SoTexture2Transform, SoTextureCoordinate2, SoTextureCoordinateFunction, SoColorMap, SoSFArray2D.
SoIndexedTexture2::SoIndexedTexture2 | ( | ) |
Constructor.
void SoIndexedTexture2::computeDataRange | ( | ) |
static SoType SoIndexedTexture2::getClassTypeId | ( | ) | [static] |
Returns the type identifier for this class.
Reimplemented from SoTexture.
virtual SoType SoIndexedTexture2::getTypeId | ( | ) | const [virtual] |
Returns the type identifier for this specific instance.
Reimplemented from SoTexture.
This field contains the in-memory representation of the indexed texture image.
Each value of this array is a color index. In the case of float values, data must be between 0 and 1.
Specifies the range of values which is mapped onto the color map (see SoColorMap).
When minValue and maxValue are equal to 0 (the default), the entire range of the data type is mapped onto the color map, except in the case of float data. For example, for a color map of size N:
All values less than or equal to minValue will be mapped to the first entry of the color map. Likewise, all values greater than or equal to maxValue will be mapped to the last entry of the color map.
This field controls the way an image with non-power-of-two dimension is handled:
Default is FALSE.
When this field is enabled, if other texture transforms are applied to the texture coordinates (especially if the texture is repeated), the unused part of the larger texture could be displayed. Furthermore, in this mode, if non-power-of-two textures occur one after another in the scene graph, an incorrect image may result because texture transforms are cumulative. For example, the following code would give incorrect results:
root->addChild( colorMap ); root->addChild( nonPowerOfTwoIndexedTexture1 ); root->addChild( nonPowerOfTwoIndexedTexture2 ); root->addChild( nonPowerOfTwoIndexedTexture3 );
The correct way is to use a separator above each texture, as shown:
root->addChild( colorMap ); root->addChild( separator1 ); separator1->addChild( nonPowerOfTwoIndexedTexture1 ); root->addChild( separator2); separator2->addChild( nonPowerOfTwoIndexedTexture2 ); root->addChild( separator3); separator3->addChild( nonPowerOfTwoIndexedTexture3 );
Indicates what to do when texture coordinates in the T (vertical) direction lie outside the range 0-1.
Use enum SoTexture::Wrap. Default is REPEAT.