    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/ogcwebservices/wpvs/configuration/RenderingConfiguration.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005     Department of Geography, University of Bonn
    006     and
    007     lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035     ----------------------------------------------------------------------------*/
    036
    037    package org.deegree.ogcwebservices.wpvs.configuration;
    038
    039    import java.awt.image.BufferedImage;
    040    import java.io.IOException;
    041    import java.io.InputStream;
    042    import java.util.Properties;
    043
    044    import javax.media.j3d.ColoringAttributes;
    045    import javax.media.j3d.PolygonAttributes;
    046    import javax.media.j3d.Texture;
    047    import javax.media.j3d.TextureAttributes;
    048    import javax.media.j3d.Transform3D;
    049    import javax.vecmath.Color4f;
    050
    051    import org.deegree.framework.log.ILogger;
    052    import org.deegree.framework.log.LoggerFactory;
    053    import org.deegree.i18n.Messages;
    054
    055    import com.sun.j3d.utils.image.TextureLoader;
    056
    057    /**
    058     * The <code>RenderingConfiguration</code> class is a simple wrapper to retrieve the configuration of the rendering
    059     * options.
    060     *
    061     * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
    062     *
    063     * @author last edited by: $Author: rbezema $
    064     *
    065     * @version $Revision: 20609 $, $Date: 2009-11-05 17:37:10 +0100 (Do, 05. Nov 2009) $
    066     *
    067     */
    068
    069    public final class RenderingConfiguration {
    070        private static ILogger LOG = LoggerFactory.getLogger( RenderingConfiguration.class );
    071
    072        private static RenderingConfiguration renderConfig;
    073
    074        private final TextureAttributes textureAttributes;
    075
    076        private final ColoringAttributes coloringAttributes;
    077
    078        private final PolygonAttributes terrainPolygonAttributes;
    079
    080        private final PolygonAttributes surfacePolygonAttributes;
    081
    082        private final boolean objectShadingEnabled;
    083
    084        /**
    085         * The renderingOptions defined in a file called rendering_options.properties
    086         */
    087        private final Properties renderingOptions;
    088
    089        private final String propertieFile = "rendering_options.properties";
    090
    091        private boolean terrainShadingEnabled;
    092
    093        private RenderingConfiguration() {
    094            // Singleton pattern
    095            renderingOptions = new Properties();
    096            try {
    097                InputStream renderingProps = RenderingConfiguration.class.getResourceAsStream( "/" + propertieFile );
    098                if ( renderingProps == null ) {
    099                    renderingProps = RenderingConfiguration.class.getResourceAsStream( propertieFile );
    100                }
    101                renderingOptions.load( renderingProps );
    102            } catch ( IOException e ) {
    103                LOG.logError( e.getMessage(), e );
    104            }
    105
    106            this.textureAttributes = createTextureAttributes();
    107            this.coloringAttributes = createColoringAttributes();
    108            this.terrainPolygonAttributes = createTerrainPolygonAttributes();
    109            this.surfacePolygonAttributes = createSurfacePolygonAttributes();
    110            this.objectShadingEnabled = optionTrueFalse( "object_shading_enabled" );
    111            this.terrainShadingEnabled = optionTrueFalse( "terrain_shading_enabled" );
    112
    113        }
    114
    115        /**
    116         * @return true if the given option fails or is not set to false,no, 0
    117         */
    118        private boolean optionTrueFalse( String option ) {
    119            boolean result = true;
    120            // finding a configured material shading property
    121            String configuredProperty = (String) renderingOptions.get( option );
    122            if ( configuredProperty != null ) {
    123                configuredProperty = configuredProperty.trim();
    124                if ( "false".equalsIgnoreCase( configuredProperty ) || "0".equalsIgnoreCase( configuredProperty )
    125                     || "no".equalsIgnoreCase( configuredProperty ) ) {
    126                    result = false;
    127                } else if ( !"TRUE".equalsIgnoreCase( configuredProperty ) || "1".equalsIgnoreCase( configuredProperty )
    128                            || "yes".equalsIgnoreCase( configuredProperty ) ) {
    129                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", option, configuredProperty,
    130                                                         "true" ) );
    131                }
    132            }
    133            return result;
    134        }
    135
    136        /**
    137         * @return the configured PolygonAttributes for surfaces
    138         */
    139        private PolygonAttributes createSurfacePolygonAttributes() {
    140            PolygonAttributes targetPolyAttr = new PolygonAttributes();
    141            targetPolyAttr.setCapability( PolygonAttributes.ALLOW_MODE_READ );
    142            targetPolyAttr.setCapability( PolygonAttributes.ALLOW_CULL_FACE_READ );
    143            targetPolyAttr.setCapability( PolygonAttributes.ALLOW_NORMAL_FLIP_READ );
    144            targetPolyAttr.setPolygonMode( PolygonAttributes.POLYGON_FILL );
    145
    146            // finding a configured backface flip property
    147            String configuredProperty = (String) renderingOptions.get( "surface_backflip" );
    148            if ( configuredProperty != null ) {
    149                configuredProperty = configuredProperty.trim();
    150                if ( "TRUE".equalsIgnoreCase( configuredProperty ) || "1".equalsIgnoreCase( configuredProperty )
    151                     || "yes".equalsIgnoreCase( configuredProperty ) ) {
    152                    targetPolyAttr.setBackFaceNormalFlip( true );
    153                } else if ( "false".equalsIgnoreCase( configuredProperty ) || "0".equalsIgnoreCase( configuredProperty )
    154                            || "no".equalsIgnoreCase( configuredProperty ) ) {
    155                    targetPolyAttr.setBackFaceNormalFlip( false );
    156                } else {
    157                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "surface_backflip",
    158                                                         configuredProperty, "false" ) );
    159                    targetPolyAttr.setBackFaceNormalFlip( false );
    160                }
    161
    162            }
    163
    164            int configuredValue = PolygonAttributes.CULL_NONE;
    165            // finding a configured surface culling
    166            configuredProperty = (String) renderingOptions.get( "surface_culling" );
    167            if ( configuredProperty != null ) {
    168                configuredProperty = configuredProperty.trim();
    169                if ( "BACK".equalsIgnoreCase( configuredProperty ) ) {
    170                    configuredValue = PolygonAttributes.CULL_BACK;
    171                } else if ( "FRONT".equalsIgnoreCase( configuredProperty ) ) {
    172                    configuredValue = PolygonAttributes.CULL_FRONT;
    173                } else if ( "NONE".equalsIgnoreCase( configuredProperty ) ) {
    174                    configuredValue = PolygonAttributes.CULL_NONE;
    175                } else {
    176                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "surface_culling",
    177                                                         configuredProperty, "NONE" ) );
    178                }
    179            }
    180            targetPolyAttr.setCullFace( configuredValue );
    181            return targetPolyAttr;
    182
    183        }
    184
    185        /**
    186         * @return the configured Polygon Attributes for the dgm (terrain)
    187         */
    188        private PolygonAttributes createTerrainPolygonAttributes() {
    189            // what kind of drawing
    190            PolygonAttributes targetPolyAttr = new PolygonAttributes();
    191            targetPolyAttr.setPolygonMode( PolygonAttributes.POLYGON_FILL );
    192
    193            // finding a configured backface flip property
    194            String configuredProperty = (String) renderingOptions.get( "terrain_backflip" );
    195            if ( configuredProperty != null ) {
    196                configuredProperty = configuredProperty.trim();
    197                if ( "true".equalsIgnoreCase( configuredProperty ) || "1".equalsIgnoreCase( configuredProperty )
    198                     || "yes".equalsIgnoreCase( configuredProperty ) ) {
    199                    targetPolyAttr.setBackFaceNormalFlip( true );
    200                } else if ( "false".equalsIgnoreCase( configuredProperty ) || "0".equalsIgnoreCase( configuredProperty )
    201                            || "no".equalsIgnoreCase( configuredProperty ) ) {
    202                    targetPolyAttr.setBackFaceNormalFlip( false );
    203                } else {
    204                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "terrain_backflip",
    205                                                         configuredProperty, "false" ) );
    206
    207                }
    208            }
    209
    210            int configuredValue = PolygonAttributes.CULL_NONE;
    211            // finding a configured surface culling
    212            configuredProperty = (String) renderingOptions.get( "terrain_culling" );
    213            if ( configuredProperty != null ) {
    214                configuredProperty = configuredProperty.trim();
    215                if ( "BACK".equalsIgnoreCase( configuredProperty ) ) {
    216                    configuredValue = PolygonAttributes.CULL_BACK;
    217                } else if ( "FRONT".equalsIgnoreCase( configuredProperty ) ) {
    218                    configuredValue = PolygonAttributes.CULL_FRONT;
    219                } else if ( "NONE".equalsIgnoreCase( configuredProperty ) ) {
    220                    configuredValue = PolygonAttributes.CULL_NONE;
    221                } else {
    222                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "terrain_culling",
    223                                                         configuredProperty, "NONE" ) );
    224                }
    225            }
    226            targetPolyAttr.setCullFace( configuredValue );
    227            return targetPolyAttr;
    228        }
    229
    230        /**
    231         * @return the conifured coloring attributes
    232         */
    233        private ColoringAttributes createColoringAttributes() {
    234            // and some Coloring attribs
    235            // the coloring attributes
    236            ColoringAttributes ca = new ColoringAttributes();
    237            int configuredValue = ColoringAttributes.SHADE_GOURAUD;
    238            // finding a configured shading model
    239            String configuredProperty = (String) renderingOptions.get( "shading_model" );
    240            if ( configuredProperty != null ) {
    241                configuredProperty = configuredProperty.trim();
    242                if ( "SHADE_FLAT".equalsIgnoreCase( configuredProperty ) ) {
    243                    configuredValue = ColoringAttributes.SHADE_FLAT;
    244                } else if ( "SHADE_GOURAUD".equalsIgnoreCase( configuredProperty ) ) {
    245                    configuredValue = ColoringAttributes.SHADE_GOURAUD;
    246                } else {
    247                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "shading_model",
    248                                                         configuredProperty, "SHADE_GOURAUD" ) );
    249
    250                }
    251
    252            }
    253            ca.setShadeModel( configuredValue );
    254
    255            configuredValue = ColoringAttributes.NICEST;
    256            // finding a configured shading model quality
    257            configuredProperty = (String) renderingOptions.get( "shading_quality" );
    258            if ( configuredProperty != null ) {
    259                configuredProperty = configuredProperty.trim();
    260                if ( "FASTEST".equalsIgnoreCase( configuredProperty ) ) {
    261                    configuredValue = ColoringAttributes.FASTEST;
    262                } else if ( "NICEST".equalsIgnoreCase( configuredProperty ) ) {
    263                    configuredValue = ColoringAttributes.NICEST;
    264                } else {
    265                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "shading_quality",
    266                                                         configuredProperty, "NICEST" ) );
    267                }
    268            }
    269            ca.setCapability( configuredValue );
    270            return ca;
    271        }
    272
    273        /**
    274         * @return the configured textureAttributes
    275         */
    276        private TextureAttributes createTextureAttributes() {
    277            int blendFunc = TextureAttributes.MODULATE;
    278            // finding a configured blending function
    279            String configuredProperty = (String) renderingOptions.get( "blend_function" );
    280            if ( configuredProperty != null ) {
    281                configuredProperty = configuredProperty.trim();
    282                if ( "BLEND".equalsIgnoreCase( configuredProperty ) ) {
    283                    blendFunc = TextureAttributes.BLEND;
    284                } else if ( "DECAL".equalsIgnoreCase( configuredProperty ) ) {
    285                    blendFunc = TextureAttributes.DECAL;
    286                } else if ( "COMBINE".equalsIgnoreCase( configuredProperty ) ) {
    287                    blendFunc = TextureAttributes.COMBINE;
    288                } else if ( "MODULATE".equalsIgnoreCase( configuredProperty ) ) {
    289                    blendFunc = TextureAttributes.MODULATE;
    290                } else {
    291                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "blend_function",
    292                                                         configuredProperty, "MODULATE" ) );
    293                }
    294            }
    295            Color4f blendColor = new Color4f( 0, 0, 0, 0 );
    296            if ( blendFunc == TextureAttributes.BLEND ) {
    297                configuredProperty = (String) renderingOptions.get( "blend_color" );
    298                if ( configuredProperty != null ) {
    299                    String[] split = configuredProperty.trim().split( "," );
    300                    if ( split != null && split.length == 4 ) {
    301                        try {
    302                            float r = Float.parseFloat( split[0] );
    303                            float g = Float.parseFloat( split[1] );
    304                            float b = Float.parseFloat( split[2] );
    305                            float a = Float.parseFloat( split[3] );
    306                            blendColor = new Color4f( r, g, b, a );
    307                        } catch ( NumberFormatException nfe ) {
    308                            LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "blend_color",
    309                                                                 configuredProperty, "0,0,0,0" ) );
    310                        }
    311                    } else {
    312                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "blend_color",
    313                                                             configuredProperty, "0,0,0,0" ) );
    314                    }
    315                }
    316            }
    317
    318            int persCorrection = TextureAttributes.NICEST;
    319            configuredProperty = (String) renderingOptions.get( "terrain_texture_perspective_correction" );
    320            if ( configuredProperty != null ) {
    321                configuredProperty = configuredProperty.trim();
    322                if ( "FASTEST".equalsIgnoreCase( configuredProperty ) ) {
    323                    persCorrection = TextureAttributes.FASTEST;
    324                } else if ( "NICEST".equalsIgnoreCase( configuredProperty ) ) {
    325                    persCorrection = TextureAttributes.NICEST;
    326                } else {
    327                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY",
    328                                                         "terrain_texture_perspective_correction", configuredProperty,
    329                                                         "NICEST" ) );
    330                }
    331            }
    332
    333            TextureAttributes textureAttribs = new TextureAttributes( blendFunc, new Transform3D(), blendColor,
    334                                                                      persCorrection );
    335
    336            if ( TextureAttributes.COMBINE == blendFunc ) {
    337                /*
    338                 * Get the configured Combine parametersof the texture attributes. first rgb then alpha
    339                 */
    340                // combineFunction type
    341                int combineFunctionRGB = TextureAttributes.COMBINE_MODULATE;
    342                configuredProperty = (String) renderingOptions.get( "combine_function_rgb" );
    343                if ( configuredProperty != null ) {
    344                    configuredProperty = configuredProperty.trim();
    345                    if ( "COMBINE_REPLACE".equalsIgnoreCase( configuredProperty ) ) {
    346                        combineFunctionRGB = TextureAttributes.COMBINE_REPLACE;
    347                    } else if ( "COMBINE_ADD".equalsIgnoreCase( configuredProperty ) ) {
    348                        combineFunctionRGB = TextureAttributes.COMBINE_ADD;
    349                    } else if ( "COMBINE_ADD_SIGNED".equalsIgnoreCase( configuredProperty ) ) {
    350                        combineFunctionRGB = TextureAttributes.COMBINE_ADD_SIGNED;
    351                    } else if ( "COMBINE_SUBTRACT".equalsIgnoreCase( configuredProperty ) ) {
    352                        combineFunctionRGB = TextureAttributes.COMBINE_SUBTRACT;
    353                    } else if ( "COMBINE_INTERPOLATE".equalsIgnoreCase( configuredProperty ) ) {
    354                        combineFunctionRGB = TextureAttributes.COMBINE_INTERPOLATE;
    355                    } else if ( "COMBINE_DOT3".equalsIgnoreCase( configuredProperty ) ) {
    356                        combineFunctionRGB = TextureAttributes.COMBINE_DOT3;
    357                    } else if ( "COMBINE_MODULATE".equalsIgnoreCase( configuredProperty ) ) {
    358                        combineFunctionRGB = TextureAttributes.COMBINE_MODULATE;
    359                    } else {
    360                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "combine_function_rbg",
    361                                                             configuredProperty, "COMBINE_MODULATE" ) );
    362                    }
    363                }
    364                textureAttribs.setCombineRgbMode( combineFunctionRGB );
    365
    366                int combineFunctionAlpha = TextureAttributes.COMBINE_MODULATE;
    367                configuredProperty = (String) renderingOptions.get( "combine_function_alpha" );
    368                if ( configuredProperty != null ) {
    369                    configuredProperty = configuredProperty.trim();
    370                    if ( "COMBINE_REPLACE".equalsIgnoreCase( configuredProperty ) ) {
    371                        combineFunctionAlpha = TextureAttributes.COMBINE_REPLACE;
    372                    } else if ( "COMBINE_ADD".equalsIgnoreCase( configuredProperty ) ) {
    373                        combineFunctionAlpha = TextureAttributes.COMBINE_ADD;
    374                    } else if ( "COMBINE_ADD_SIGNED".equalsIgnoreCase( configuredProperty ) ) {
    375                        combineFunctionAlpha = TextureAttributes.COMBINE_ADD_SIGNED;
    376                    } else if ( "COMBINE_SUBTRACT".equalsIgnoreCase( configuredProperty ) ) {
    377                        combineFunctionAlpha = TextureAttributes.COMBINE_SUBTRACT;
    378                    } else if ( "COMBINE_INTERPOLATE".equalsIgnoreCase( configuredProperty ) ) {
    379                        combineFunctionAlpha = TextureAttributes.COMBINE_INTERPOLATE;
    380                    } else if ( "COMBINE_DOT3".equalsIgnoreCase( configuredProperty ) ) {
    381                        combineFunctionAlpha = TextureAttributes.COMBINE_DOT3;
    382                    } else if ( "COMBINE_MODULATE".equalsIgnoreCase( configuredProperty ) ) {
    383                        combineFunctionAlpha = TextureAttributes.COMBINE_MODULATE;
    384                    } else {
    385                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "combine_function_alpha",
    386                                                             configuredProperty, "COMBINE_MODULATE" ) );
    387                    }
    388                }
    389                textureAttribs.setCombineAlphaMode( combineFunctionAlpha );
    390
    391                // Combine source Color configuration
    392                int combineColorSourceRGB = TextureAttributes.COMBINE_TEXTURE_COLOR;
    393                for ( int i = 0; ++i < 3; ) {
    394                    if ( i == 1 ) {
    395                        combineColorSourceRGB = TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE;
    396                    } else if ( i == 2 ) {
    397                        combineColorSourceRGB = TextureAttributes.COMBINE_CONSTANT_COLOR;
    398                    }
    399                    String propertyString = "combine_color_source_rgb_" + i;
    400                    configuredProperty = (String) renderingOptions.get( propertyString );
    401                    if ( configuredProperty != null ) {
    402                        configuredProperty = configuredProperty.trim();
    403                        if ( "COMBINE_TEXTURE_COLOR".equalsIgnoreCase( configuredProperty ) ) {
    404                            combineColorSourceRGB = TextureAttributes.COMBINE_TEXTURE_COLOR;
    405                        } else if ( "COMBINE_CONSTANT_COLOR".equalsIgnoreCase( configuredProperty ) ) {
    406                            combineColorSourceRGB = TextureAttributes.COMBINE_CONSTANT_COLOR;
    407                        } else if ( "COMBINE_PREVIOUS_TEXTURE_UNIT_STATE".equalsIgnoreCase( configuredProperty ) ) {
    408                            combineColorSourceRGB = TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE;
    409                        } else if ( "COMBINE_OBJECT_COLOR".equalsIgnoreCase( configuredProperty ) ) {
    410                            combineColorSourceRGB = TextureAttributes.COMBINE_OBJECT_COLOR;
    411                        } else {
    412                            LOG.logWarning( Messages.getMessage(
    413                                                                 "WPVS_UNKNOWN_RENDERING_PROPERTY",
    414                                                                 propertyString,
    415                                                                 configuredProperty,
    416                                                                 ( ( i == 0 ) ? "COMBINE_MODULATE"
    417                                                                             : ( ( i == 1 ) ? "COMBINE_PREVIOUS_TEXTURE_UNIT_STATE"
    418                                                                                           : "COMBINE_CONSTANT_COLOR" ) ) ) );
    419                        }
    420
    421                    }
    422                    textureAttribs.setCombineRgbSource( i, combineColorSourceRGB );
    423                }
    424
    425                int combineColorSourceAlpha = TextureAttributes.COMBINE_TEXTURE_COLOR;
    426                for ( int i = 0; ++i < 3; ) {
    427                    if ( i == 1 ) {
    428                        combineColorSourceAlpha = TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE;
    429                    } else if ( i == 2 ) {
    430                        combineColorSourceAlpha = TextureAttributes.COMBINE_CONSTANT_COLOR;
    431                    }
    432
    433                    String propertyString = "combine_color_source_alpha_" + i;
    434                    configuredProperty = (String) renderingOptions.get( propertyString );
    435                    if ( configuredProperty != null ) {
    436                        configuredProperty = configuredProperty.trim();
    437                        if ( "COMBINE_TEXTURE_COLOR".equalsIgnoreCase( configuredProperty ) ) {
    438                            combineColorSourceAlpha = TextureAttributes.COMBINE_TEXTURE_COLOR;
    439                        } else if ( "COMBINE_CONSTANT_COLOR".equalsIgnoreCase( configuredProperty ) ) {
    440                            combineColorSourceAlpha = TextureAttributes.COMBINE_CONSTANT_COLOR;
    441                        } else if ( "COMBINE_PREVIOUS_TEXTURE_UNIT_STATE".equalsIgnoreCase( configuredProperty ) ) {
    442                            combineColorSourceAlpha = TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE;
    443                        } else if ( "COMBINE_OBJECT_COLOR".equalsIgnoreCase( configuredProperty ) ) {
    444                            combineColorSourceAlpha = TextureAttributes.COMBINE_OBJECT_COLOR;
    445                        } else {
    446                            LOG.logWarning( Messages.getMessage(
    447                                                                 "WPVS_UNKNOWN_RENDERING_PROPERTY",
    448                                                                 propertyString,
    449                                                                 configuredProperty,
    450                                                                 ( ( i == 0 ) ? "COMBINE_MODULATE"
    451                                                                             : ( ( i == 1 ) ? "COMBINE_PREVIOUS_TEXTURE_UNIT_STATE"
    452                                                                                           : "COMBINE_CONSTANT_COLOR" ) ) ) );
    453                        }
    454                    }
    455                    textureAttribs.setCombineAlphaSource( i, combineColorSourceAlpha );
    456                }
    457
    458                // Combine color function to use
    459                int combineColorFunctionRGB = TextureAttributes.COMBINE_SRC_COLOR;
    460                configuredProperty = (String) renderingOptions.get( "combine_color_function_rgb" );
    461                if ( configuredProperty != null ) {
    462                    configuredProperty = configuredProperty.trim();
    463                    if ( "COMBINE_ONE_MINUS_SRC_COLOR".equalsIgnoreCase( configuredProperty ) ) {
    464                        combineColorFunctionRGB = TextureAttributes.COMBINE_ONE_MINUS_SRC_COLOR;
    465                    } else if ( "COMBINE_SRC_COLOR".equalsIgnoreCase( configuredProperty ) ) {
    466                        combineColorFunctionRGB = TextureAttributes.COMBINE_SRC_COLOR;
    467                    } else {
    468                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY",
    469                                                             "combine_color_function_rgb", configuredProperty,
    470                                                             "COMBINE_SRC_COLOR" ) );
    471                    }
    472
    473                }
    474                textureAttribs.setCombineRgbFunction( 0, combineColorFunctionRGB );
    475                textureAttribs.setCombineRgbFunction( 1, combineColorFunctionRGB );
    476                textureAttribs.setCombineRgbFunction( 2, combineColorFunctionRGB );
    477
    478                int combineColorFunctionAlpha = TextureAttributes.COMBINE_SRC_ALPHA;
    479                configuredProperty = (String) renderingOptions.get( "combine_color_function_alpha" );
    480                if ( configuredProperty != null ) {
    481                    configuredProperty = configuredProperty.trim();
    482                    if ( "COMBINE_ONE_MINUS_SRC_ALPHA".equalsIgnoreCase( configuredProperty ) ) {
    483                        combineColorFunctionAlpha = TextureAttributes.COMBINE_ONE_MINUS_SRC_ALPHA;
    484                    } else if ( "COMBINE_SRC_ALPHA".equalsIgnoreCase( configuredProperty ) ) {
    485                        combineColorFunctionAlpha = TextureAttributes.COMBINE_SRC_ALPHA;
    486                    } else {
    487                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY",
    488                                                             "combine_color_function_alpha", configuredProperty,
    489                                                             "COMBINE_SRC_ALPHA" ) );
    490                    }
    491                }
    492                textureAttribs.setCombineAlphaFunction( 0, combineColorFunctionAlpha );
    493                textureAttribs.setCombineAlphaFunction( 1, combineColorFunctionAlpha );
    494                textureAttribs.setCombineAlphaFunction( 2, combineColorFunctionAlpha );
    495
    496                // And the scale of the output color
    497                int combineScaleFactorRGB = 1;
    498                configuredProperty = (String) renderingOptions.get( "combine_scale_factor_rgb" );
    499                if ( configuredProperty != null ) {
    500                    configuredProperty = configuredProperty.trim();
    501                    try {
    502                        combineScaleFactorRGB = Integer.parseInt( configuredProperty );
    503                    } catch ( NumberFormatException nfe ) {
    504                        combineScaleFactorRGB = 1;
    505                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "combine_scale_factor_rgb",
    506                                                             configuredProperty, "1" ) );
    507                    }
    508                    if ( combineScaleFactorRGB != 1 && combineScaleFactorRGB != 2 && combineScaleFactorRGB != 4 ) {
    509                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "combine_scale_factor_rgb",
    510                                                             configuredProperty, "1" ) );
    511                        combineScaleFactorRGB = 1;
    512
    513                    }
    514                }
    515                textureAttribs.setCombineRgbScale( combineScaleFactorRGB );
    516
    517                int combineScaleFactorAlpha = 1;
    518                configuredProperty = (String) renderingOptions.get( "combine_scale_factor_alpha" );
    519                if ( configuredProperty != null ) {
    520                    configuredProperty = configuredProperty.trim();
    521                    try {
    522                        combineScaleFactorAlpha = Integer.parseInt( configuredProperty );
    523                    } catch ( NumberFormatException nfe ) {
    524                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY",
    525                                                             "combine_scale_factor_alpha", configuredProperty, "1" ) );
    526
    527                        combineScaleFactorAlpha = 1;
    528                    }
    529                    if ( combineScaleFactorAlpha != 1 && combineScaleFactorAlpha != 2 && combineScaleFactorAlpha != 4 ) {
    530                        LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY",
    531                                                             "combine_scale_factor_alpha", configuredProperty, "1" ) );
    532                        combineScaleFactorAlpha = 1;
    533                    }
    534                }
    535                textureAttribs.setCombineAlphaScale( combineScaleFactorAlpha );
    536            }
    537            return textureAttribs;
    538        }
    539
    540        /**
    541         * @return gets a RenderingConfiguration as a singleton pattern.
    542         */
    543        public static synchronized RenderingConfiguration getInstance() {
    544            if ( renderConfig == null ) {
    545                renderConfig = new RenderingConfiguration();
    546            }
    547            return renderConfig;
    548        }
    549
    550        /**
    551         * @return the coloringAttributes, Configured rendering properties valid for all rendered primitives.
    552         */
    553        public final ColoringAttributes getColoringAttributes() {
    554            return coloringAttributes;
    555        }
    556
    557        /**
    558         * @return the TextureAttributes, Configured rendering properties valid for all rendered textured primitives.
    559         */
    560        public final TextureAttributes getTextureAttributes() {
    561            return textureAttributes;
    562        }
    563
    564        /**
    565         * @return the surfacePolygonAttributes, Configured rendering properties for the rendered surfaces.
    566         */
    567        public final PolygonAttributes getSurfacePolygonAttributes() {
    568            return surfacePolygonAttributes;
    569        }
    570
    571        /**
    572         * @return the terrainPolygonAttributes, Configured rendering properties for the rendered terrain.
    573         */
    574        public final PolygonAttributes getTerrainPolygonAttributes() {
    575            return terrainPolygonAttributes;
    576        }
    577
    578        /**
    579         * @param textureImage
    580         *            the image to load as a texture
    581         * @return a Texture with loaded according the configured mipmap properties.
    582         */
    583        public final Texture getTexture( BufferedImage textureImage ) {
    584            TextureLoader tl = null;
    585            boolean isMipMapped = true;
    586            String configuredProperty = (String) renderingOptions.get( "terrain_texture_mipmapping" );
    587            if ( configuredProperty != null ) {
    588                configuredProperty = configuredProperty.trim();
    589                if ( "TRUE".equalsIgnoreCase( configuredProperty ) || "1".equalsIgnoreCase( configuredProperty )
    590                     || "yes".equalsIgnoreCase( configuredProperty ) ) {
    591                    tl = new TextureLoader( textureImage, TextureLoader.GENERATE_MIPMAP );
    592                } else if ( "false".equalsIgnoreCase( configuredProperty ) || "0".equalsIgnoreCase( configuredProperty )
    593                            || "no".equalsIgnoreCase( configuredProperty ) ) {
    594                    tl = new TextureLoader( textureImage );
    595                } else {
    596                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "terrain_texture_mipmapping",
    597                                                         configuredProperty, "false" ) );
    598                    tl = new TextureLoader( textureImage );
    599                }
    600            } else {
    601                tl = new TextureLoader( textureImage, TextureLoader.GENERATE_MIPMAP );
    602            }
    603
    604            configuredProperty = (String) renderingOptions.get( "terrain_anisotropic_filter" );
    605            int anisotropic = Texture.ANISOTROPIC_SINGLE_VALUE;
    606            if ( configuredProperty != null ) {
    607                configuredProperty = configuredProperty.trim();
    608                if ( "NONE".equalsIgnoreCase( configuredProperty ) ) {
    609                    anisotropic = Texture.ANISOTROPIC_NONE;
    610
    611                } else if ( !"SINGLE_VALUE".equalsIgnoreCase( configuredProperty ) ) {
    612                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "terrain_anisotropic_filter",
    613                                                         configuredProperty, "SINGLE_VALUE" ) );
    614                }
    615            }
    616
    617            configuredProperty = (String) renderingOptions.get( "terrain_texture_filter" );
    618            int textureFilter = Texture.NICEST;
    619            if ( configuredProperty != null ) {
    620                configuredProperty = configuredProperty.trim().toUpperCase();
    621                if ( "FASTEST".equals( configuredProperty ) ) {
    622                    // uses the fastest available method for processing geometry.
    623                    textureFilter = Texture.FASTEST;
    624                } else if ( "NICEST".equals( configuredProperty ) ) {
    625                    // uses the nicest available method for processing geometry
    626                    // nottin
    627                } else if ( "BASE_LEVEL_POINT".equals( configuredProperty ) ) {
    628                    // selects the nearest texel in the base level texture image
    629                    textureFilter = Texture.BASE_LEVEL_POINT;
    630                } else if ( "BASE_LEVEL_LINEAR".equals( configuredProperty ) ) {
    631                    // performs a bilinear interpolation on the four nearest texels in the base level texture image
    632                    textureFilter = Texture.BASE_LEVEL_LINEAR;
    633                } else if ( "LINEAR_SHARPEN".equals( configuredProperty ) ) {
    634                    // sharpens the resulting image by extrapolating from the base level plus one image to the base level
    635                    // image of this texture object
    636                    textureFilter = Texture.LINEAR_SHARPEN;
    637                } else if ( "LINEAR_SHARPEN_RGB".equals( configuredProperty ) ) {
    638                    // performs linear sharpen filter for the rgb components only. The alpha component is computed using
    639                    // BASE_LEVEL_LINEAR filter
    640                    textureFilter = Texture.LINEAR_SHARPEN_RGB;
    641                } else if ( "LINEAR_SHARPEN_ALPHA".equals( configuredProperty ) ) {
    642                    // performs linear sharpen filter for the alpha component only. The rgb components are computed using
    643                    // BASE_LEVEL_LINEAR filter.
    644                    textureFilter = Texture.LINEAR_SHARPEN_ALPHA;
    645                } else if ( "FILTER4".equals( configuredProperty ) ) {
    646                    // applies an application-supplied weight function on the nearest 4x4 texels in the base level texture
    647                    // image
    648                    textureFilter = Texture.FILTER4;
    649                } else {
    650                    LOG.logWarning( Messages.getMessage( "WPVS_UNKNOWN_RENDERING_PROPERTY", "terrain_texture_filter",
    651                                                         configuredProperty, "FASTEST" ) );
    652                }
    653            }
    654
    655            Texture texture = tl.getTexture();
    656            texture.setEnable( true );
    657            texture.setAnisotropicFilterMode( anisotropic );
    658            texture.setMagFilter( textureFilter );
    659            texture.setMinFilter( textureFilter );
    660
    661            // texture.setAnisotropicFilterMode( Texture.ANISOTROPIC_SINGLE_VALUE );
    662            texture.setCapability( Texture.ALLOW_ENABLE_READ | ( ( isMipMapped ) ? Texture.ALLOW_MIPMAP_MODE_READ : 0 )
    663                                   | Texture.CLAMP_TO_EDGE );
    664            return texture;
    665        }
    666
    667        /**
    668         * @return the useMaterialShading
    669         */
    670        public boolean isObjectShadingEnabled() {
    671            return objectShadingEnabled;
    672        }
    673
    674        /**
    675         * @return the terrainShadingEnabled
    676         */
    677        public final boolean isTerrainShadingEnabled() {
    678            return terrainShadingEnabled;
    679        }
    680    }