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