/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.scenegraph;
import org.jagatoo.opengl.enums.DrawMode;
import org.jagatoo.opengl.enums.FaceCullMode;
import org.openmali.vecmath2.Colorf;
import org.xith3d.effects.EffectFactory;
import org.xith3d.effects.textureprojection.TextureProjectionFactory;
import org.xith3d.loaders.texture.TextureLoader;
import org.xith3d.render.CanvasPeer;
import org.xith3d.render.OpenGLCapabilities;
import org.xith3d.scenegraph.modifications.ScenegraphModificationsListener;
/**
* Appearance is a component object of a Shape3D node that defines all rendering
* state attributes for that shape node.
*
* @author David Yazel
* @author Marvin Froehlich (aka Qudus)
* @author Florian Hofmann (aka Goliat) [GLSL Shader support]
* @author Amos Wenger (aka BlueSky) [Convenience methods]
*/
public class Appearance extends NodeComponent
{
/**
* The used ShaderProgram, that bypasses the GL fixed function pipeline.
*/
private ShaderProgramContext< ? > shaderProgramContext = null;
/**
* The desired transparency attribute properties.
*/
private TransparencyAttributes transparencyAttrs = null;
/**
* The desired material properties used for lighting.
*/
private Material material = null;
/**
* The desired coloring attribute properties.
*/
private ColoringAttributes coloringAttrs = null;
/**
* The desired rendering attribute properties.
*/
private RenderingAttributes renderingAttrs = null;
/**
* The desired polygon attribute properties.
*/
private PolygonAttributes polygonAttrs = null;
/**
* The desired line attribute properties.
*/
private LineAttributes lineAttrs = null;
/**
* The desired point attribute properties.
*/
private PointAttributes pointAttrs = null;
private TextureUnit[] textureUnits = null;
private static long nextChangeId = 1L;
/**
* Flag for appearance change
*/
private long changeID = 0L;
private static boolean defaultStaticApp = false;
private boolean staticApp = defaultStaticApp;
private boolean staticDirty = true;
public static final void setDefaultStatic( boolean b )
{
defaultStaticApp = b;
}
public static final boolean isDefaultStatic()
{
return ( defaultStaticApp );
}
public final void setStatic( boolean b )
{
this.staticApp = b;
}
public final boolean isStatic()
{
return ( staticApp );
}
public void markStaticDirty()
{
this.staticDirty = true;
}
final void markStaticClean()
{
this.staticDirty = false;
}
public final boolean isStaticDirty()
{
return ( staticDirty );
}
@Override
public void setModListener( ScenegraphModificationsListener modListener )
{
super.setModListener( modListener );
if ( shaderProgramContext != null )
shaderProgramContext.setModListener( modListener );
if ( transparencyAttrs != null )
transparencyAttrs.setModListener( modListener );
if ( material != null )
material.setModListener( modListener );
if ( coloringAttrs != null )
coloringAttrs.setModListener( modListener );
if ( renderingAttrs != null )
renderingAttrs.setModListener( modListener );
if ( polygonAttrs != null )
polygonAttrs.setModListener( modListener );
if ( lineAttrs != null )
lineAttrs.setModListener( modListener );
if ( pointAttrs != null )
pointAttrs.setModListener( modListener );
if ( textureUnits != null )
{
for ( int i = 0; i < textureUnits.length; i++ )
{
if ( textureUnits[ i ] != null )
textureUnits[ i ].setModListener( modListener );
}
}
}
/**
* Sets the material information.
*/
public final void setMaterial( Material material )
{
this.material = material;
setChanged( true );
if ( material != null )
material.setModListener( getModListener() );
}
/**
* @return the material information.
*/
public final Material getMaterial()
{
return ( material );
}
/**
* @param forceExistence if this appearance has no material, create one and
* return it.
* @return the material information, or create one if necessary
*/
public final Material getMaterial( boolean forceExistence )
{
if ( forceExistence && ( getMaterial() == null ) )
{
setMaterial( new Material() );
}
return ( getMaterial() );
}
/**
* Sets the Texture of the given TextureUnit.
*
* @param unit
* @param texture
*/
public final void setTexture( int unit, Texture texture )
{
if ( this.textureUnits == null )
{
this.textureUnits = new TextureUnit[ unit + 1 ];
this.textureUnits[ unit ] = new TextureUnit( texture );
}
else if ( this.textureUnits.length <= unit )
{
TextureUnit[] textureUnits = new TextureUnit[ unit + 1 ];
System.arraycopy( this.textureUnits, 0, textureUnits, 0, this.textureUnits.length );
textureUnits[ unit ] = new TextureUnit( texture );
this.textureUnits = textureUnits;
}
else if ( this.textureUnits[ unit ] == null )
{
this.textureUnits[ unit ] = new TextureUnit( texture );
}
else
{
this.textureUnits[ unit ].setTexture( texture );
}
if ( texture != null )
texture.setChanged( true );
setChanged( true );
if ( texture != null )
texture.setModListener( getModListener() );
}
/**
* Sets the Texture of the first (#0) TextureUnit.
*
* @param texture
*/
public final void setTexture( Texture texture )
{
setTexture( 0, texture );
}
/**
* Sets the Texture of the first (#0) TextureUnit.
*
* @param texture
*/
public final void setTexture( int unit, String texture )
{
if ( texture == null )
setTexture( unit, (Texture)null );
else
setTexture( unit, TextureLoader.getInstance().getTexture( texture ) );
}
/**
* Sets the Texture of the first (#0) TextureUnit.
*
* @param texture
*/
public final void setTexture( String texture )
{
if ( texture == null )
setTexture( 0, (Texture)null );
else
setTexture( 0, TextureLoader.getInstance().getTexture( texture ) );
}
/**
* @return the Texture of the requested TextureUnit.
*
* @param unit
*/
public final Texture getTexture( int unit )
{
if ( ( textureUnits == null ) || ( textureUnits.length <= unit ) || ( textureUnits[ unit ] == null ) )
return ( null );
return ( textureUnits[ unit ].getTexture() );
}
/**
* @return the Texture of the first (#0) TextureUnit.
*/
public final Texture getTexture()
{
return ( getTexture( 0 ) );
}
/**
* Sets the TextureAttributes of the given TextureUnit.
*
* @param unit
* @param textureAttribs
*/
public final void setTextureAttributes( int unit, TextureAttributes textureAttribs )
{
if ( this.textureUnits == null )
{
this.textureUnits = new TextureUnit[ unit + 1 ];
this.textureUnits[ unit ] = new TextureUnit( (Texture)null, textureAttribs );
}
else if ( this.textureUnits.length <= unit )
{
TextureUnit[] textureUnits = new TextureUnit[ unit + 1 ];
System.arraycopy( this.textureUnits, 0, textureUnits, 0, this.textureUnits.length );
textureUnits[ unit ] = new TextureUnit( (Texture)null, textureAttribs );
this.textureUnits = textureUnits;
}
else if ( this.textureUnits[ unit ] == null )
{
this.textureUnits[ unit ] = new TextureUnit( (Texture)null, textureAttribs );
}
else
{
this.textureUnits[ unit ].setTextureAttributes( textureAttribs );
}
if ( textureAttribs != null )
textureAttribs.setChanged( true );
setChanged( true );
if ( textureAttribs != null )
textureAttribs.setModListener( getModListener() );
}
/**
* Sets the TextureAttributes of the first (#0) TextureUnit.
*
* @param textureAttribs
*/
public final void setTextureAttributes( TextureAttributes textureAttribs )
{
setTextureAttributes( 0, textureAttribs );
}
/**
* @return the TextureAttributes of the requested TextureUnit.
*
* @param unit
*/
public final TextureAttributes getTextureAttributes( int unit )
{
if ( ( textureUnits == null ) || ( textureUnits.length <= unit ) || ( textureUnits[ unit ] == null ) )
return ( null );
return ( textureUnits[ unit ].getTextureAttributes() );
}
/**
* @return the TextureAttributes of the requested TextureUnit.
*
* @param unit
*/
public final TextureAttributes getTextureAttributes( int unit, boolean forceExistence )
{
if ( ( getTextureAttributes( unit ) == null ) && ( forceExistence ) )
{
setTextureAttributes( unit, new TextureAttributes() );
}
return ( getTextureAttributes( unit ) );
}
/**
* @return the TextureAttributes of the first (#0) TextureUnit.
*/
public final TextureAttributes getTextureAttributes()
{
return ( getTextureAttributes( 0 ) );
}
/**
* @return the TextureAttributes of the first (#0) TextureUnit.
*/
public final TextureAttributes getTextureAttributes( boolean forceExistence )
{
if ( ( getTextureAttributes() == null ) && ( forceExistence ) )
{
setTextureAttributes( new TextureAttributes() );
}
return ( getTextureAttributes() );
}
/**
* Sets the TexCoordGeneration of the given TextureUnit.
*
* @param unit
* @param texCoordGen
*/
public final void setTexCoordGeneration( int unit, TexCoordGeneration texCoordGen )
{
if ( this.textureUnits == null )
{
this.textureUnits = new TextureUnit[ unit + 1 ];
this.textureUnits[ unit ] = new TextureUnit( (Texture)null, null, texCoordGen );
}
else if ( this.textureUnits.length <= unit )
{
TextureUnit[] textureUnits = new TextureUnit[ unit + 1 ];
System.arraycopy( this.textureUnits, 0, textureUnits, 0, this.textureUnits.length );
textureUnits[ unit ] = new TextureUnit( (Texture)null, null, texCoordGen );
this.textureUnits = textureUnits;
}
else if ( this.textureUnits[ unit ] == null )
{
this.textureUnits[ unit ] = new TextureUnit( (Texture)null, null, texCoordGen );
}
else
{
this.textureUnits[ unit ].setTexCoordGeneration( texCoordGen );
}
if ( texCoordGen != null )
texCoordGen.setChanged( true );
setChanged( true );
if ( texCoordGen != null )
texCoordGen.setModListener( getModListener() );
}
/**
* Sets the TexCoordGeneration of the first (#0) TextureUnit.
*
* @param texCoordGen
*/
public final void setTexCoordGeneration( TexCoordGeneration texCoordGen )
{
setTexCoordGeneration( 0, texCoordGen );
}
/**
* @return the TexCoordGeneration of the requested TextureUnit.
*
* @param unit
*/
public final TexCoordGeneration getTexCoordGeneration( int unit )
{
if ( ( textureUnits == null ) || ( textureUnits.length <= unit ) || ( textureUnits[ unit ] == null ) )
return ( null );
return ( textureUnits[ unit ].getTexCoordGeneration() );
}
/**
* @return the TexCoordGeneration of the requested TextureUnit.
*
* @param unit
*/
public final TexCoordGeneration getTexCoordGeneration( int unit, boolean forceExistence )
{
if ( ( getTexCoordGeneration( unit ) == null ) && ( forceExistence ) )
{
setTexCoordGeneration( unit, new TexCoordGeneration() );
}
return ( getTexCoordGeneration( unit ) );
}
/**
* @return the TexCoordGeneration of the first (#0) TextureUnit.
*/
public final TexCoordGeneration getTexCoordGeneration()
{
return ( getTexCoordGeneration( 0 ) );
}
/**
* @return the TexCoordGeneration of the first (#0) TextureUnit.
*/
public final TexCoordGeneration getTexCoordGeneration( boolean forceExistence )
{
if ( ( getTexCoordGeneration() == null ) && ( forceExistence ) )
{
setTexCoordGeneration( new TexCoordGeneration() );
}
return ( getTexCoordGeneration() );
}
private static final void applyProjTU( Appearance app, ProjectiveTextureUnit projTU )
{
final EffectFactory effFact = EffectFactory.getInstance();
if ( effFact != null )
{
final TextureProjectionFactory texProjFact = effFact.getTextureProjectionFactory();
if ( texProjFact != null )
texProjFact.onProjectiveTextureApplied( app, projTU );
}
}
public final void setTextureUnits( TextureUnit... textureUnits )
{
if ( this.textureUnits != null )
{
for ( int i = 0; i < this.textureUnits.length; i++ )
{
final TextureUnit tu = this.textureUnits[ i ];
if ( tu instanceof ProjectiveTextureUnit )
{
applyProjTU( null, (ProjectiveTextureUnit)tu );
}
tu.setModListener( null );
}
}
if ( textureUnits == null )
{
this.textureUnits = null;
}
else
{
if ( ( this.textureUnits == null ) || ( this.textureUnits.length != textureUnits.length ) )
this.textureUnits = new TextureUnit[ textureUnits.length ];
System.arraycopy( textureUnits, 0, this.textureUnits, 0, textureUnits.length );
}
if ( this.textureUnits != null )
{
for ( int i = 0; i < this.textureUnits.length; i++ )
{
final TextureUnit tu = this.textureUnits[ i ];
if ( tu instanceof ProjectiveTextureUnit )
{
applyProjTU( this, (ProjectiveTextureUnit)tu );
}
tu.setModListener( getModListener() );
}
}
setChanged( true );
}
public final void setTextureUnit( int index, TextureUnit tu )
{
if ( ( this.textureUnits != null ) && ( this.textureUnits.length > index ) && ( this.textureUnits[ index ] != null ) )
{
final TextureUnit tu_ = this.textureUnits[ index ];
if ( tu_ instanceof ProjectiveTextureUnit )
{
applyProjTU( null, (ProjectiveTextureUnit)tu_ );
}
tu_.setModListener( null );
}
if ( textureUnits == null )
{
textureUnits = new TextureUnit[ index + 1 ];
}
else if ( textureUnits.length <= index )
{
TextureUnit[] textureUnits2 = new TextureUnit[ index + 1 ];
System.arraycopy( textureUnits, 0, textureUnits2, 0, textureUnits.length );
textureUnits = textureUnits2;
}
textureUnits[ index ] = tu;
setChanged( true );
if ( this.textureUnits[ index ] != null )
{
final TextureUnit tu_ = this.textureUnits[ index ];
if ( tu_ instanceof ProjectiveTextureUnit )
{
applyProjTU( this, (ProjectiveTextureUnit)tu_ );
}
tu_.setModListener( getModListener() );
}
}
public final TextureUnit[] getTextureUnits()
{
return ( textureUnits );
}
public TextureUnit getTextureUnit( int index )
{
if ( ( textureUnits == null ) || ( textureUnits.length <= index ) )
return ( null );
return ( textureUnits[ index ] );
}
public int getTextureUnitsCount()
{
if ( textureUnits == null )
return ( 0 );
return ( textureUnits.length );
}
/**
* Sets the ShaderProgram information.
*/
@SuppressWarnings("unchecked")
public final void setShaderProgramContext( ShaderProgramContext shaderProgramContext )
{
this.shaderProgramContext = shaderProgramContext;
setChanged( true );
if ( shaderProgramContext != null )
shaderProgramContext.setModListener( getModListener() );
}
/**
* @return the ShaderProgram information
*/
@SuppressWarnings("unchecked")
public final ShaderProgramContext getShaderProgramContext()
{
return ( shaderProgramContext );
}
/**
* Sets the coloring attributes information.
*/
public final void setColoringAttributes( ColoringAttributes coloringAttrs )
{
this.coloringAttrs = coloringAttrs;
setChanged( true );
if ( coloringAttrs != null )
coloringAttrs.setModListener( getModListener() );
}
/**
* @return the coloring attributes information.
*/
public final ColoringAttributes getColoringAttributes()
{
return ( coloringAttrs );
}
/**
* @return the coloring attributes information.
*/
public final ColoringAttributes getColoringAttributes( boolean forceExistance )
{
if ( ( getColoringAttributes() == null ) && ( forceExistance ) )
{
setColoringAttributes( new ColoringAttributes() );
}
return ( getColoringAttributes() );
}
/**
* Sets the transparency attributes information.
*/
public final void setTransparencyAttributes( TransparencyAttributes transparencyAttrs )
{
this.transparencyAttrs = transparencyAttrs;
setChanged( true );
if ( transparencyAttrs != null )
transparencyAttrs.setModListener( getModListener() );
}
/**
* @return the transparency attributes information.
*/
public final TransparencyAttributes getTransparencyAttributes()
{
return ( transparencyAttrs );
}
/**
* @return the transparency attributes information.
*/
/**
* Returns this Appearance'es TransparencyAttributes, if they exist. If they
* don't exist, they are created depending on the <b>forceExistance</b>
* parameter.
*
* @param forceExistance if true, a new TransparencyAttributes is created
* and attached, if it doesn't already exist.
*
* @return the TransparencyAttributes for this object
*/
public final TransparencyAttributes getTransparencyAttributes( boolean forceExistance )
{
if ( ( getTransparencyAttributes() == null ) && ( forceExistance ) )
{
setTransparencyAttributes( new TransparencyAttributes() );
}
return ( getTransparencyAttributes() );
}
/**
* Sets the rendering attributes information.
*/
public final void setRenderingAttributes( RenderingAttributes renderingAttrs )
{
this.renderingAttrs = renderingAttrs;
setChanged( true );
if ( renderingAttrs != null )
renderingAttrs.setModListener( getModListener() );
}
/**
* @return the rendering attributes information.
*/
public final RenderingAttributes getRenderingAttributes()
{
return ( renderingAttrs );
}
/**
* @return the rendering attributes information.
*/
public final RenderingAttributes getRenderingAttributes( boolean forceExistence )
{
if ( ( getRenderingAttributes() == null ) && ( forceExistence ) )
{
setRenderingAttributes( new RenderingAttributes() );
}
return ( getRenderingAttributes() );
}
/**
* Sets the polygon attributes information.
*/
public final void setPolygonAttributes( PolygonAttributes polygonAttrs )
{
this.polygonAttrs = polygonAttrs;
setChanged( true );
if ( polygonAttrs != null )
polygonAttrs.setModListener( getModListener() );
}
/**
* @return the polygon attributes information.
*/
public final PolygonAttributes getPolygonAttributes()
{
return ( polygonAttrs );
}
/**
* @return the polygon attributes information.
*/
public final PolygonAttributes getPolygonAttributes( boolean forceExistence )
{
if ( ( getPolygonAttributes() == null ) && ( forceExistence ) )
{
setPolygonAttributes( new PolygonAttributes() );
}
return ( getPolygonAttributes() );
}
/**
* Sets the line attributes information.
*/
public final void setLineAttributes( LineAttributes lineAttrs )
{
this.lineAttrs = lineAttrs;
setChanged( true );
if ( lineAttrs != null )
lineAttrs.setModListener( getModListener() );
}
/**
* @return the line attributes information.
*/
public final LineAttributes getLineAttributes()
{
return ( lineAttrs );
}
/**
* @return the line attributes information.
*/
public final LineAttributes getLineAttributes( boolean forceExistence )
{
if ( ( getLineAttributes() == null ) && ( forceExistence ) )
{
setLineAttributes( new LineAttributes() );
}
return ( getLineAttributes() );
}
/**
* Sets the point attributes information.
*/
public final void setPointAttributes( PointAttributes pointAttrs )
{
this.pointAttrs = pointAttrs;
setChanged( true );
if ( pointAttrs != null )
pointAttrs.setModListener( getModListener() );
}
/**
* @return the point attributes information.
*/
public final PointAttributes getPointAttributes()
{
return ( pointAttrs );
}
/**
* @return the point attributes information.
*/
public final PointAttributes getPointAttributes( boolean forceExistance )
{
if ( ( getPointAttributes() == null ) && ( forceExistance ) )
{
setPointAttributes( new PointAttributes() );
}
return ( getPointAttributes() );
}
@Override
public void setChanged( boolean changed )
{
super.setChanged( changed );
if ( !changed )
{
if ( this.shaderProgramContext != null )
this.shaderProgramContext.setChanged( false );
if ( this.coloringAttrs != null )
this.coloringAttrs.setChanged( false );
if ( this.material != null )
this.material.setChanged( false );
if ( this.transparencyAttrs != null )
this.transparencyAttrs.setChanged( false );
if ( this.renderingAttrs != null )
this.renderingAttrs.setChanged( false );
if ( this.polygonAttrs != null )
this.polygonAttrs.setChanged( false );
if ( this.lineAttrs != null )
this.lineAttrs.setChanged( false );
if ( this.pointAttrs != null )
this.pointAttrs.setChanged( false );
if ( this.textureUnits != null )
{
for ( int i = 0; i < this.textureUnits.length; i++ )
if ( this.textureUnits[ i ] != null )
this.textureUnits[ i ].setChanged( false );
}
}
}
public void setChangedRecursive( boolean changed )
{
super.setChanged( changed );
if ( this.shaderProgramContext != null )
this.shaderProgramContext.setChanged( changed );
if ( this.coloringAttrs != null )
this.coloringAttrs.setChanged( changed );
if ( this.material != null )
this.material.setChanged( changed );
if ( this.transparencyAttrs != null )
this.transparencyAttrs.setChanged( changed );
if ( this.renderingAttrs != null )
this.renderingAttrs.setChanged( changed );
if ( this.polygonAttrs != null )
this.polygonAttrs.setChanged( changed );
if ( this.lineAttrs != null )
this.lineAttrs.setChanged( changed );
if ( this.pointAttrs != null )
this.pointAttrs.setChanged( changed );
if ( this.textureUnits != null )
{
for ( int i = 0; i < this.textureUnits.length; i++ )
if ( this.textureUnits[ i ] != null )
this.textureUnits[ i ].setChangedRecursive( changed );
}
}
public final long verifyChange( Shape3D shape, OpenGLCapabilities glCaps )
{
if ( isChanged() )
{
changeID = nextChangeId++;
if ( !isStatic() || isStaticDirty() )
shape.getAtom().updateStateUnits( this, glCaps );
setChanged( false );
}
return ( changeID );
}
/*
* !!!!!!!!!!!!! Convenience methods begin here (Amos Wenger) !!!!!!!!!!!!!
*/
/**
* Sets the color of this object, creating a ColoringAttributes if needed.
*
* @param color Color value
*/
public void setColor( Colorf color )
{
getColoringAttributes( true ).setColor( color );
}
/**
* Sets the color of this object, creating a ColoringAttributes if needed.
*
* @param r Red value
* @param g Green value
* @param b Blue value
*/
public void setColor( float r, float g, float b )
{
getColoringAttributes( true ).setColor( r, g, b );
}
/**
* Changes the face culling mode.
*
* @param mode The new culling mode. Can be PolygonAttributes.CULL_NONE,
* PolygonAttributes.CULL_BACK, or PolygonAttributes.CULL_FRONT
*/
public void setFaceCullMode( FaceCullMode mode )
{
getPolygonAttributes( true ).setFaceCullMode( mode );
}
/**
* Changes the draw mode
*
* @param drawMode The new draw mode. Can be PolygonAttributes.POLYGON_FILL,
* PolygonAttributes.POLYGON_LINE,
* PolygonAttributes.POLYGON_POINT
*/
public void setDrawMode( DrawMode drawMode )
{
getPolygonAttributes( true ).setDrawMode( drawMode );
}
@Override
public boolean isChanged()
{
if ( super.isChanged() )
return ( true );
if ( this.shaderProgramContext != null && this.shaderProgramContext.isChanged() )
return ( true );
if ( this.coloringAttrs != null && this.coloringAttrs.isChanged() )
return ( true );
if ( this.material != null && this.material.isChanged() )
return ( true );
if ( this.transparencyAttrs != null && this.transparencyAttrs.isChanged() )
return ( true );
if ( this.renderingAttrs != null && this.renderingAttrs.isChanged() )
return ( true );
if ( this.polygonAttrs != null && this.polygonAttrs.isChanged() )
return ( true );
if ( this.lineAttrs != null && this.lineAttrs.isChanged() )
return ( true );
if ( this.pointAttrs != null && this.pointAttrs.isChanged() )
return ( true );
if ( this.textureUnits != null )
{
for ( int i = 0; i < this.textureUnits.length; i++ )
if ( this.textureUnits[ i ] != null && this.textureUnits[ i ].isChanged() )
return ( true );
}
return ( false );
}
@Override
protected void duplicateNodeComponent( NodeComponent originalNodeComponent, boolean forceDuplicate )
{
super.duplicateNodeComponent( originalNodeComponent, forceDuplicate );
final Appearance origApp = (Appearance)originalNodeComponent;
if ( origApp.getTextureUnits() != null )
{
final TextureUnit[] origTUs = origApp.getTextureUnits();
final TextureUnit[] clonedTUs = new TextureUnit[ origTUs.length ];
for ( int i = 0; i < origTUs.length; i++ )
{
clonedTUs[ i ] = origTUs[ i ].cloneNodeComponent( forceDuplicate );
}
this.setTextureUnits( clonedTUs );
}
if ( forceDuplicate )
{
if ( origApp.getMaterial() != null )
{
setMaterial( origApp.getMaterial().cloneNodeComponent( true ) );
}
setShaderProgramContext( origApp.getShaderProgramContext() );
if ( origApp.getColoringAttributes() != null )
{
setColoringAttributes( origApp.getColoringAttributes().cloneNodeComponent( true ) );
}
if ( origApp.getTransparencyAttributes() != null )
{
setTransparencyAttributes( origApp.getTransparencyAttributes().cloneNodeComponent( true ) );
}
if ( origApp.getRenderingAttributes() != null )
{
setRenderingAttributes( origApp.getRenderingAttributes().cloneNodeComponent( true ) );
}
if ( origApp.getPolygonAttributes() != null )
{
setPolygonAttributes( origApp.getPolygonAttributes().cloneNodeComponent( true ) );
}
if ( origApp.getLineAttributes() != null )
{
setLineAttributes( origApp.getLineAttributes().cloneNodeComponent( true ) );
}
if ( origApp.getPointAttributes() != null )
{
setPointAttributes( origApp.getPointAttributes().cloneNodeComponent( true ) );
}
}
else
{
setMaterial( origApp.getMaterial() );
setShaderProgramContext( origApp.getShaderProgramContext() );
setColoringAttributes( origApp.getColoringAttributes() );
setTransparencyAttributes( origApp.getTransparencyAttributes() );
setRenderingAttributes( origApp.getRenderingAttributes() );
setPolygonAttributes( origApp.getPolygonAttributes() );
setLineAttributes( origApp.getLineAttributes() );
setPointAttributes( origApp.getPointAttributes() );
}
}
@Override
public Appearance cloneNodeComponent( boolean forceDuplicate )
{
Appearance a = new Appearance();
a.duplicateNodeComponent( this, forceDuplicate );
return ( a );
}
/**
* {@inheritDoc}
*/
@Override
public void freeOpenGLResources( CanvasPeer canvasPeer )
{
if ( shaderProgramContext != null )
shaderProgramContext.freeOpenGLResources( canvasPeer );
if ( transparencyAttrs != null )
transparencyAttrs.freeOpenGLResources( canvasPeer );
if ( material != null )
material.freeOpenGLResources( canvasPeer );
if ( coloringAttrs != null )
coloringAttrs.freeOpenGLResources( canvasPeer );
if ( renderingAttrs != null )
renderingAttrs.freeOpenGLResources( canvasPeer );
if ( polygonAttrs != null )
polygonAttrs.freeOpenGLResources( canvasPeer );
if ( lineAttrs != null )
lineAttrs.freeOpenGLResources( canvasPeer );
if ( pointAttrs != null )
pointAttrs.freeOpenGLResources( canvasPeer );
if ( textureUnits != null )
{
for ( int i = 0; i < textureUnits.length; i++ )
{
if ( textureUnits[ i ] != null )
textureUnits[ i ].freeOpenGLResources( canvasPeer );
}
}
}
/**
* Constructs a new Appearance object.
*/
public Appearance()
{
super( false );
}
/**
* Constructs a new Appearance object.
*
* @param texture
*/
public Appearance( Texture texture )
{
this();
setTexture( texture );
}
/**
* Constructs a new Appearance object.
*
* @param texture
*/
public Appearance( String texture )
{
this();
setTexture( texture );
}
}