001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_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    }