/** * Copyright (c) 2003-2009, Xith3D Project Group all rights reserved. * * Portions based on the Java3D interface, Copyright by Sun Microsystems. * Many thanks to the developers of Java3D and Sun Microsystems for their * innovation and design. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the 'Xith3D Project Group' nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE */ package org.xith3d.ui.hud.menusystem.menus.settings; import java.util.HashMap; import org.xith3d.render.config.CanvasConstructionInfo; import org.xith3d.render.config.DisplayMode; import org.xith3d.render.config.DisplayModeSelector; import org.xith3d.render.config.FSAA; import org.xith3d.render.config.OpenGLLayer; import org.xith3d.render.config.DisplayMode.FullscreenMode; import org.xith3d.ui.hud.base.AbstractList; import org.xith3d.ui.hud.base.StateButton; import org.xith3d.ui.hud.layout.ListLayout; import org.xith3d.ui.hud.listeners.WidgetEventsReceiverAdapter; import org.xith3d.ui.hud.menusystem.menus.MenuBase; import org.xith3d.ui.hud.utils.HUDFont; import org.xith3d.ui.hud.widgets.Checkbox; import org.xith3d.ui.hud.widgets.ComboBox; import org.xith3d.ui.hud.widgets.EmptyWidget; import org.xith3d.ui.hud.widgets.Label; import org.xith3d.ui.text2d.TextAlignment; /** * This is a settings menu for main graphics settings. * * @author Marvin Froehlich (aka Qudus) */ public class GraphicsMainSettingsMenu extends MenuBase { public static final String NAME = GraphicsMainSettingsMenu.class.getSimpleName(); private final Label openGLLayerCaption; private final ComboBox openGLLayer; private final Label displayModeCaption; private final ComboBox displayMode; private final Label fsaaCaption; private final ComboBox fsaa; private final Checkbox vsync; private final Checkbox fullscreen; private final HashMap<String, DisplayMode> displayModeMap = new HashMap<String, DisplayMode>(); private final HashMap<OpenGLLayer, DisplayMode[]> openGLLayerDisplayModesMap = new HashMap<OpenGLLayer, DisplayMode[]>(); private final void refillDisplayModes( DisplayMode oldDisplayMode, OpenGLLayer openGLLayer ) { this.displayMode.removeSelectionListener( eventsHandler ); displayMode.clear(); displayMode.addItems( openGLLayerDisplayModesMap.get( openGLLayer ) ); final DisplayModeSelector dspModeSelector = DisplayModeSelector.getImplementation( openGLLayer ); int found = 0; int selIndex = 0; for ( int i = 0; i < this.displayMode.getItemsCount(); i++ ) { final String[] modeParts = this.displayMode.getItem( i ).toString().split( "x" ); final int width = Integer.parseInt( modeParts[ 0 ] ); final int height = Integer.parseInt( modeParts[ 1 ] ); final int bpp; if ( modeParts[ 2 ].equals( "?" ) ) bpp = 24; else bpp = Integer.parseInt( modeParts[ 2 ] ); final int freq; if ( modeParts[ 3 ].equals( "?" ) ) freq = 75; else freq = Integer.parseInt( modeParts[ 3 ] ); switch ( found ) { case 0: { final DisplayMode dm0 = dspModeSelector.getBestMode( width, height ); if ( dm0.getWidth() == oldDisplayMode.getWidth() && dm0.getHeight() == oldDisplayMode.getHeight() ) { selIndex = i; found = 1; } break; } case 1: { final DisplayMode dm1 = dspModeSelector.getBestMode( width, height, bpp ); if ( dm1.getWidth() == oldDisplayMode.getWidth() && dm1.getHeight() == oldDisplayMode.getHeight() && dm1.getBPP() == oldDisplayMode.getBPP() ) { selIndex = i; found = 2; } break; } case 2: { final DisplayMode dm2 = dspModeSelector.getBestMode( width, height, bpp, freq ); if ( dm2.getWidth() == oldDisplayMode.getWidth() && dm2.getHeight() == oldDisplayMode.getHeight() && dm2.getBPP() == oldDisplayMode.getBPP() && dm2.getFrequency() == oldDisplayMode.getFrequency() ) { selIndex = i; } break; } } } this.displayMode.addSelectionListener( eventsHandler ); if ( this.displayMode.getItemsCount() > 0 ) this.displayMode.setSelectedIndex( selIndex ); } public void setOpenGLLayer( OpenGLLayer openGLLayer ) { final OpenGLLayer oldOpenGLLayer = getOpenGLLayer(); final DisplayMode oldDisplayMode = getDisplayMode(); if ( openGLLayer != oldOpenGLLayer ) { this.openGLLayer.setSelectedIndex( this.openGLLayer.findItem( openGLLayer ) ); refillDisplayModes( oldDisplayMode, openGLLayer ); } } public final OpenGLLayer getOpenGLLayer() { return ( (OpenGLLayer)this.openGLLayer.getSelectedItem() ); } public void setDisplayMode( DisplayMode displayMode ) { this.displayMode.setSelectedIndex( this.displayMode.findItem( displayMode.toLightString() ) ); } public final DisplayMode getDisplayMode() { return ( displayModeMap.get( this.displayMode.getSelectedItem().toString() ) ); } public void setFSAA( FSAA fsaa ) { this.fsaa.setSelectedIndex( this.fsaa.findItem( fsaa ) ); } public final FSAA getFSAA() { return ( (FSAA)this.fsaa.getSelectedItem() ); } public void setVSync( boolean vsync ) { this.vsync.setState( vsync ); } public final boolean getVSync() { return ( this.vsync.getState() ); } public void setFullscreenMode( FullscreenMode fullscreen ) { this.fullscreen.setState( fullscreen.isFullscreen() ); } public final FullscreenMode getFullscreenMode() { return ( this.fullscreen.getState() ? FullscreenMode.FULLSCREEN : FullscreenMode.WINDOWED ); } /** * Applies the {@link CanvasConstructionInfo} to this settings menu. * * @param canvasInfo */ public void applyConfig( CanvasConstructionInfo canvasInfo ) { setOpenGLLayer( canvasInfo.getOpenGLLayer() ); setDisplayMode( canvasInfo.getDisplayMode() ); setFSAA( canvasInfo.getFSAAMode() ); setVSync( canvasInfo.isVSyncEnabled() ); setFullscreenMode( canvasInfo.getFullscreenMode() ); } /** * Reads the relevant settings from this settings menu * and applies it to the {@link CanvasConstructionInfo}. * * @param canvasInfo */ public void extractConfig( CanvasConstructionInfo canvasInfo ) { canvasInfo.setOpenGLLayer( getOpenGLLayer() ); canvasInfo.setDisplayMode( getDisplayMode() ); canvasInfo.setFSAAMode( getFSAA() ); canvasInfo.setVSyncEnabled( getVSync() ); canvasInfo.setFullscreenMode( getFullscreenMode() ); } /** * {@inheritDoc} */ @Override protected float getPickHeight() { return ( getHeight() + 100f ); // add a little to the pick-height to make all the ComboBoxes reachable. } /** * {@inheritDoc} */ @Override protected void initWidgets() { addWidget( openGLLayerCaption ); addWidget( openGLLayer ); addWidget( new EmptyWidget( 0f, 10f ) ); addWidget( displayModeCaption ); addWidget( displayMode ); addWidget( new EmptyWidget( 0f, 10f ) ); addWidget( fsaaCaption ); addWidget( fsaa ); addWidget( new EmptyWidget( 0f, 10f ) ); addWidget( vsync ); addWidget( new EmptyWidget( 0f, 10f ) ); addWidget( fullscreen ); } private final WidgetEventsReceiverAdapter eventsHandler = new WidgetEventsReceiverAdapter() { @Override public void onListSelectionChanged( AbstractList list, Object oldSelectedItem, Object newSelectedItem, int oldSelectedIndex, int newSelectedIndex ) { if ( list == openGLLayer ) { final DisplayMode oldDisplayMode = displayModeMap.get( String.valueOf( oldSelectedItem ) + "-" + displayMode.getSelectedItem() ); final OpenGLLayer ogl = (OpenGLLayer)newSelectedItem; refillDisplayModes( oldDisplayMode, ogl ); getMenuGroup().fireOnSettingChanged( GraphicsMainSettingsMenu.this, "OpenGLLayer", getOpenGLLayer() ); } else if ( list == displayMode ) { getMenuGroup().fireOnSettingChanged( GraphicsMainSettingsMenu.this, "DisplayMode", getDisplayMode() ); } else if ( list == fsaa ) { getMenuGroup().fireOnSettingChanged( GraphicsMainSettingsMenu.this, "FSAA", getFSAA() ); } } @Override public void onButtonStateChanged( StateButton stateButton, boolean state, Object userObject ) { if ( stateButton == vsync ) { getMenuGroup().fireOnSettingChanged( GraphicsMainSettingsMenu.this, "vsync", getVSync() ); } else if ( stateButton == fullscreen ) { getMenuGroup().fireOnSettingChanged( GraphicsMainSettingsMenu.this, "fullscreenMode", getFullscreenMode() ); } } }; private final ComboBox createDisplayModeCombo( OpenGLLayer oglLayer ) { ComboBox cb = ComboBox.newTextCombo( 0f, 20f ); OpenGLLayer[] ogls = new OpenGLLayer[] { OpenGLLayer.JOGL_AWT, OpenGLLayer.LWJGL }; for ( OpenGLLayer ogl: ogls ) { DisplayMode[] displayModes = DisplayModeSelector.getImplementation( ogl ).getAvailableModes(); for ( DisplayMode displayMode: displayModes ) { this.displayModeMap.put( ogl.toString() + "-" + displayMode.toLightString(), displayMode ); if ( ogl == oglLayer ) { cb.addItem( displayMode ); } } openGLLayerDisplayModesMap.put( ogl, displayModes ); } return ( cb ); } public GraphicsMainSettingsMenu( float width, float height ) { super( width, height, GraphicsMainSettingsMenu.NAME, new String[] { "save" } ); ListLayout layout = new ListLayout( ListLayout.Orientation.VERTICAL, 2f, 10f, 10f, 10f, 10f ); layout.setAlignment( ListLayout.Alignment.CENTER_TOP ); layout.setOtherSpanCalculated( true ); this.setLayout( layout ); HUDFont font = HUDFont.getFont( "Verdana", HUDFont.PLAIN, 12 ); final OpenGLLayer defaultOGL = OpenGLLayer.JOGL_AWT; this.openGLLayerCaption = new Label( 0f, 0f, "OpenGLLayer", font, TextAlignment.BOTTOM_LEFT ); this.openGLLayer = ComboBox.newTextCombo( 0f, 20f ); openGLLayer.addItem( OpenGLLayer.JOGL_AWT ); openGLLayer.addItem( OpenGLLayer.LWJGL ); this.displayModeCaption = new Label( 0f, 0f, "Display-Mode", font, TextAlignment.BOTTOM_LEFT ); this.displayMode = createDisplayModeCombo( defaultOGL ); this.fsaaCaption = new Label( 0f, 0f, "Full Scene Anti-Aliasing", font, TextAlignment.BOTTOM_LEFT ); this.fsaa = ComboBox.newTextCombo( 0f, 20f ); fsaa.addItem( FSAA.OFF ); fsaa.addItem( FSAA.ON_2X ); fsaa.addItem( FSAA.ON_4X ); fsaa.addItem( FSAA.ON_8X ); fsaa.addItem( FSAA.ON_16X ); this.vsync = new Checkbox( 0f, 0f, "Vertical-Sync", font, null ); this.fullscreen = new Checkbox( 0f, 0f, "Fullscreen", font, null ); // Apply default settings... openGLLayer.setSelectedIndex( 0 ); displayMode.setSelectedIndex( 0 ); fsaa.setSelectedIndex( 0 ); vsync.setState( true ); fullscreen.setState( true ); // add event handlers... openGLLayer.addSelectionListener( eventsHandler ); displayMode.addSelectionListener( eventsHandler ); fsaa.addSelectionListener( eventsHandler ); vsync.addStateListener( eventsHandler ); fullscreen.addStateListener( eventsHandler ); } public GraphicsMainSettingsMenu( float width ) { this( width, 0f ); setMinimalHeight(); } }