Merge pull request #14 from bkuker/kruland-integration-decals

Decal UI Simplification & Fixes
This commit is contained in:
kruland2607 2012-12-14 08:21:27 -08:00
commit 1bbef243ac
8 changed files with 220 additions and 79 deletions

View File

@ -27,6 +27,8 @@ public class AppearanceBuilder extends AbstractChangeSource {
private String image; private String image;
private Decal.EdgeMode edgeMode; private Decal.EdgeMode edgeMode;
private boolean batch;
public AppearanceBuilder() { public AppearanceBuilder() {
resetToDefaults(); resetToDefaults();
} }
@ -217,7 +219,15 @@ public class AppearanceBuilder extends AbstractChangeSource {
@Override @Override
protected void fireChangeEvent() { protected void fireChangeEvent() {
super.fireChangeEvent(); if ( !batch )
super.fireChangeEvent();
}
public void batch(Runnable r){
batch = true;
r.run();
batch = false;
fireChangeEvent();
} }
} }

View File

@ -0,0 +1,77 @@
package net.sf.openrocket.appearance;
import net.sf.openrocket.util.Color;
public class SimpleAppearanceBuilder extends AppearanceBuilder {
public SimpleAppearanceBuilder() {
super();
}
public SimpleAppearanceBuilder(Appearance a) {
super(a);
}
public Color getColor() {
return getDiffuse();
}
public void setColor(final Color c) {
batch(new Runnable() {
@Override
public void run() {
setAmbient(c);
setDiffuse(c);
}
});
}
public void setShine(final int s) {
batch(new Runnable() {
@Override
public void run() {
setShininess(s);
int c = (int) (s * 2.55);
setSpecular(new net.sf.openrocket.util.Color(c, c, c));
}
});
}
public int getShine() {
return getShininess();
}
private Color oldColor = null;
@Override
public void setImage(final String image) {
batch(new Runnable() {
@Override
public void run() {
if (getImage() == null && image != null) {
oldColor = getColor();
setColor(new Color(255, 255, 255));
} else if (getImage() != null && image == null && oldColor != null) {
setColor(oldColor);
}
SimpleAppearanceBuilder.super.setImage(image);
}
});
}
public double getScaleX() {
return 1.0 / super.getScaleU();
}
public void setScaleX(double scaleU) {
super.setScaleU(1.0 / scaleU);
}
public double getScaleY() {
return 1.0 / super.getScaleV();
}
public void setScaleY(double scaleV) {
super.setScaleV(1.0 / scaleV);
}
}

View File

@ -15,10 +15,13 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import net.sf.openrocket.file.FileInfo; import net.sf.openrocket.file.FileInfo;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.FileUtils; import net.sf.openrocket.util.FileUtils;
public class DecalRegistry { public class DecalRegistry {
private static LogHelper log = Application.getLogger();
private FileInfo fileInfo; private FileInfo fileInfo;
private boolean isZipFile = false; private boolean isZipFile = false;
@ -105,7 +108,12 @@ public class DecalRegistry {
if ( rawIs == null ) { if ( rawIs == null ) {
File decal = new File(name); File decal = new File(name);
if ( decal.isAbsolute() ) { if ( decal.isAbsolute() ) {
rawIs = new FileInputStream(decal); try {
rawIs = new FileInputStream(decal);
} catch ( FileNotFoundException e ){
name = decal.getName();
log.debug("Unable to find absolute file" + decal + ", falling back to " + name);
}
} }
} }

View File

@ -6,6 +6,8 @@ import java.util.ArrayList;
import java.util.EventListener; import java.util.EventListener;
import java.util.EventObject; import java.util.EventObject;
import javax.swing.BoundedRangeModel;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.SpinnerModel; import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel; import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
@ -83,7 +85,44 @@ public class IntegerModel implements StateChangeListener {
return new IntegerSpinnerModel(); return new IntegerSpinnerModel();
} }
private class ValueSliderModel extends DefaultBoundedRangeModel implements BoundedRangeModel, StateChangeListener {
ValueSliderModel(){
super(IntegerModel.this.getValue(), 0, minValue, maxValue);
}
@Override
public void setValue(int newValue) {
IntegerModel.this.setValue(newValue);
}
@Override
public int getValue(){
return IntegerModel.this.getValue();
}
@Override
public void stateChanged(EventObject e) {
IntegerModel.this.fireStateChanged();
}
@Override
public void addChangeListener(ChangeListener l) {
IntegerModel.this.addChangeListener(l);
}
@Override
public void removeChangeListener(ChangeListener l) {
IntegerModel.this.removeChangeListener(l);
}
}
/**
* Returns a new BoundedRangeModel with the same base as the IntegerModel.
*
* @return A compatibility layer for Sliders.
*/
public BoundedRangeModel getSliderModel(){
return new ValueSliderModel();
}
//////////// Main model ///////////// //////////// Main model /////////////

View File

@ -14,12 +14,13 @@ import javax.swing.JDialog;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.appearance.AppearanceBuilder;
import net.sf.openrocket.appearance.Decal.EdgeMode; import net.sf.openrocket.appearance.Decal.EdgeMode;
import net.sf.openrocket.appearance.SimpleAppearanceBuilder;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.BooleanModel;
@ -46,7 +47,7 @@ import net.sf.openrocket.util.StateChangeListener;
public class AppearancePanel extends JPanel { public class AppearancePanel extends JPanel {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
private AppearanceBuilder ab; private SimpleAppearanceBuilder ab;
private final static UnitGroup UNIT_FOR_SCALES = new UnitGroup(); private final static UnitGroup UNIT_FOR_SCALES = new UnitGroup();
static { static {
@ -108,16 +109,19 @@ public class AppearancePanel extends JPanel {
public AppearancePanel(final OpenRocketDocument document, final RocketComponent c) { public AppearancePanel(final OpenRocketDocument document, final RocketComponent c) {
super(new MigLayout("fill", "[150][grow][150][grow]")); super(new MigLayout("fill", "[150][grow][150][grow]"));
ab = new AppearanceBuilder(c.getAppearance()); ab = new SimpleAppearanceBuilder(c.getAppearance());
net.sf.openrocket.util.Color figureColor = c.getColor(); net.sf.openrocket.util.Color figureColor = c.getColor();
if (figureColor == null) { if (figureColor == null) {
figureColor = Application.getPreferences().getDefaultColor(c.getClass()); figureColor = Application.getPreferences().getDefaultColor(c.getClass());
} }
final JButton figureColorButton = new JButton(new ColorIcon(figureColor)); final JButton figureColorButton = new JButton(new ColorIcon(figureColor));
final JButton diffuseColorButton = new JButton(new ColorIcon(ab.getDiffuse()));
/*final JButton diffuseColorButton = new JButton(new ColorIcon(ab.getDiffuse()));
final JButton ambientColorButton = new JButton(new ColorIcon(ab.getAmbient())); final JButton ambientColorButton = new JButton(new ColorIcon(ab.getAmbient()));
final JButton specularColorButton = new JButton(new ColorIcon(ab.getSpecular())); final JButton specularColorButton = new JButton(new ColorIcon(ab.getSpecular()));*/
final JButton colorButton = new JButton(new ColorIcon(ab.getAmbient()));
final JComboBox textureDropDown = new JComboBox( new DecalModel(this,document,ab));; final JComboBox textureDropDown = new JComboBox( new DecalModel(this,document,ab));;
@ -125,9 +129,10 @@ public class AppearancePanel extends JPanel {
@Override @Override
public void stateChanged(EventObject e) { public void stateChanged(EventObject e) {
figureColorButton.setIcon(new ColorIcon(c.getColor())); figureColorButton.setIcon(new ColorIcon(c.getColor()));
diffuseColorButton.setIcon(new ColorIcon(ab.getDiffuse())); /*diffuseColorButton.setIcon(new ColorIcon(ab.getDiffuse()));
ambientColorButton.setIcon(new ColorIcon(ab.getAmbient())); ambientColorButton.setIcon(new ColorIcon(ab.getAmbient()));
specularColorButton.setIcon(new ColorIcon(ab.getSpecular())); specularColorButton.setIcon(new ColorIcon(ab.getSpecular()));*/
colorButton.setIcon(new ColorIcon(ab.getColor()));
c.setAppearance(ab.getAppearance()); c.setAppearance(ab.getAppearance());
} }
}); });
@ -144,9 +149,10 @@ public class AppearancePanel extends JPanel {
}); });
figureColorButton.addActionListener(new ColorActionListener(c, "Color")); figureColorButton.addActionListener(new ColorActionListener(c, "Color"));
diffuseColorButton.addActionListener(new ColorActionListener(ab, "Diffuse")); colorButton.addActionListener(new ColorActionListener(ab, "Color"));
/*diffuseColorButton.addActionListener(new ColorActionListener(ab, "Diffuse"));
ambientColorButton.addActionListener(new ColorActionListener(ab, "Ambient")); ambientColorButton.addActionListener(new ColorActionListener(ab, "Ambient"));
specularColorButton.addActionListener(new ColorActionListener(ab, "Specular")); specularColorButton.addActionListener(new ColorActionListener(ab, "Specular"));*/
BooleanModel mDefault = new BooleanModel(c.getAppearance() == null); BooleanModel mDefault = new BooleanModel(c.getAppearance() == null);
BooleanModel fDefault = new BooleanModel(c.getColor() == null); BooleanModel fDefault = new BooleanModel(c.getColor() == null);
@ -213,7 +219,7 @@ public class AppearancePanel extends JPanel {
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx"); add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
{// Texture Header Row {// Texture Header Row
add(new StyledLabel(trans.get("AppearanceCfg.lbl.Appearance"), Style.BOLD)); add(new StyledLabel(trans.get("AppearanceCfg.lbl.Appearance"), Style.BOLD), "wrap");
final JCheckBox materialDefault = new JCheckBox(mDefault); final JCheckBox materialDefault = new JCheckBox(mDefault);
materialDefault.addActionListener(new ActionListener() { materialDefault.addActionListener(new ActionListener() {
@ -226,11 +232,6 @@ public class AppearancePanel extends JPanel {
} }
} }
}); });
materialDefault.setText(trans.get("AppearanceCfg.lbl.Usedefault"));
add(materialDefault);
JButton setMDefault = new JButton(trans.get("AppearanceCfg.but.savedefault"));
mDefault.addEnableComponent(setMDefault, false);
add(setMDefault, "span 2, align right, wrap");
} }
{// Texture File {// Texture File
@ -241,34 +242,47 @@ public class AppearancePanel extends JPanel {
add(p, "span 3, growx, wrap"); add(p, "span 3, growx, wrap");
} }
{ // Diffuse /*{ // Diffuse
add(new JLabel(trans.get("AppearanceCfg.lbl.color.diffuse"))); add(new JLabel(trans.get("AppearanceCfg.lbl.color.diffuse")));
mDefault.addEnableComponent(diffuseColorButton, false); mDefault.addEnableComponent(diffuseColorButton, false);
add(diffuseColorButton); add(diffuseColorButton);
}*/
{ // Color
add(new JLabel("Color"));
mDefault.addEnableComponent(colorButton, false);
add(colorButton);
} }
{ // Scale { // Scale
add(new JLabel(trans.get("AppearanceCfg.lbl.texture.scale"))); add(new JLabel(trans.get("AppearanceCfg.lbl.texture.scale")));
add(new JLabel("x:"), "split 4"); add(new JLabel("x:"), "split 4");
JSpinner scaleU = new JSpinner(new DoubleModel(ab, "ScaleU",UNIT_FOR_SCALES).getSpinnerModel()); JSpinner scaleU = new JSpinner(new DoubleModel(ab, "ScaleX",UNIT_FOR_SCALES).getSpinnerModel());
scaleU.setEditor(new SpinnerEditor(scaleU)); scaleU.setEditor(new SpinnerEditor(scaleU));
mDefault.addEnableComponent(scaleU, false); mDefault.addEnableComponent(scaleU, false);
add(scaleU, "w 40"); add(scaleU, "w 40");
add(new JLabel("y:")); add(new JLabel("y:"));
JSpinner scaleV = new JSpinner(new DoubleModel(ab, "ScaleV",UNIT_FOR_SCALES).getSpinnerModel()); JSpinner scaleV = new JSpinner(new DoubleModel(ab, "ScaleY",UNIT_FOR_SCALES).getSpinnerModel());
scaleV.setEditor(new SpinnerEditor(scaleV)); scaleV.setEditor(new SpinnerEditor(scaleV));
mDefault.addEnableComponent(scaleV, false); mDefault.addEnableComponent(scaleV, false);
add(scaleV, "wrap, w 40"); add(scaleV, "wrap, w 40");
} }
{ // Ambient {// Placeholder
add(new JLabel(trans.get("AppearanceCfg.lbl.color.ambient"))); add(new JLabel(trans.get("AppearanceCfg.lbl.shine")));
mDefault.addEnableComponent(ambientColorButton, false); IntegerModel shineModel = new IntegerModel(ab, "Shine", 0, 100);
add(ambientColorButton); JSpinner spin = new JSpinner(shineModel.getSpinnerModel());
JSlider slide = new JSlider(shineModel.getSliderModel());
mDefault.addEnableComponent(slide, false);
mDefault.addEnableComponent(spin, false);
add(spin, "split 2, w 50");
add(slide, "w 100");
} }
{ // Offset { // Offset
add(new JLabel(trans.get("AppearanceCfg.lbl.texture.offset"))); add(new JLabel(trans.get("AppearanceCfg.lbl.texture.offset")));
@ -285,35 +299,15 @@ public class AppearancePanel extends JPanel {
add(offsetV, "wrap, w 40"); add(offsetV, "wrap, w 40");
} }
{ // Specular { // Repeat
add(new JLabel(trans.get("AppearanceCfg.lbl.color.specular"))); add(new JLabel(trans.get("AppearanceCfg.lbl.texture.repeat")));
mDefault.addEnableComponent(specularColorButton, false); EdgeMode[] list = new EdgeMode[EdgeMode.values().length + 1];
add(specularColorButton); System.arraycopy(EdgeMode.values(), 0, list, 1, EdgeMode.values().length);
JComboBox combo = new JComboBox(new EnumModel<EdgeMode>(ab, "EdgeMode", list));
mDefault.addEnableComponent(combo, false);
add(combo);
} }
{ // Center
add(new JLabel(trans.get("AppearanceCfg.lbl.texture.center")));
add(new JLabel("x:"), "split 4");
JSpinner centerU = new JSpinner(new DoubleModel(ab, "CenterU").getSpinnerModel());
centerU.setEditor(new SpinnerEditor(centerU));
mDefault.addEnableComponent(centerU, false);
add(centerU, "w 40");
add(new JLabel("y:"));
JSpinner centerV = new JSpinner(new DoubleModel(ab, "CenterV").getSpinnerModel());
centerV.setEditor(new SpinnerEditor(centerV));
mDefault.addEnableComponent(centerV, false);
add(centerV, "wrap, w 40");
}
{ // Shine
add(new JLabel(trans.get("AppearanceCfg.lbl.shine")));
IntegerModel shineModel = new IntegerModel(ab, "Shininess", 0, 128);
JSpinner shine = new JSpinner(shineModel.getSpinnerModel());
mDefault.addEnableComponent(shine, false);
add(shine, "w 50");
}
{ // Rotation { // Rotation
add(new JLabel(trans.get("AppearanceCfg.lbl.texture.rotation"))); add(new JLabel(trans.get("AppearanceCfg.lbl.texture.rotation")));
@ -328,18 +322,6 @@ public class AppearancePanel extends JPanel {
add(bs, "w 100, wrap"); add(bs, "w 100, wrap");
} }
{// Placeholder
add(new JLabel(""), "span 2");
}
{ // Repeat
add(new JLabel(trans.get("AppearanceCfg.lbl.texture.repeat")));
EdgeMode[] list = new EdgeMode[EdgeMode.values().length + 1];
System.arraycopy(EdgeMode.values(), 0, list, 1, EdgeMode.values().length);
JComboBox combo = new JComboBox(new EnumModel<EdgeMode>(ab, "EdgeMode", list));
mDefault.addEnableComponent(combo, false);
add(combo);
}
} }

View File

@ -5,6 +5,7 @@ import java.util.HashMap;
import javax.media.opengl.GL; import javax.media.opengl.GL;
import javax.media.opengl.GL2; import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES1; import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.fixedfunc.GLLightingFunc; import javax.media.opengl.fixedfunc.GLLightingFunc;
import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.BodyTube;
@ -97,7 +98,29 @@ public class FigureRenderStrategy extends RenderStrategy {
} }
@Override
public void init(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glLightModelfv(GL2ES1.GL_LIGHT_MODEL_AMBIENT,
new float[] { 0,0,0 }, 0);
float amb = 0.3f;
float dif = 1.0f - amb;
float spc = 1.0f;
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_AMBIENT,
new float[] { amb, amb, amb, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_DIFFUSE,
new float[] { dif, dif, dif, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR,
new float[] { spc, spc, spc, 1 }, 0);
gl.glEnable(GLLightingFunc.GL_LIGHT1);
gl.glEnable(GLLightingFunc.GL_LIGHTING);
gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
gl.glEnable(GLLightingFunc.GL_NORMALIZE);
}
private static int getShine(RocketComponent c) { private static int getShine(RocketComponent c) {
if (c instanceof ExternalComponent) { if (c instanceof ExternalComponent) {

View File

@ -131,20 +131,22 @@ public class RocketRenderer {
gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GLLightingFunc.GL_SPECULAR, colorBlack, 0); gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GLLightingFunc.GL_SPECULAR, colorBlack, 0);
gl.glLineWidth(5.0f); gl.glLineWidth(5.0f);
for (RocketComponent c : selection) { for (RocketComponent c : configuration) {
//Draw as lines, set Z to nearest if ( selection.contains(c) ){
gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_LINE); //Draw as lines, set Z to nearest
gl.glDepthRange(0, 0); gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_LINE);
cr.renderGeometry(gl, c); gl.glDepthRange(0, 0);
cr.renderGeometry(gl, c);
//Draw polygons, always passing depth test, //Draw polygons, always passing depth test,
//setting Z to farthest //setting Z to farthest
gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL); gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL);
gl.glDepthRange(1, 1); gl.glDepthRange(1, 1);
gl.glDepthFunc(GL.GL_ALWAYS); gl.glDepthFunc(GL.GL_ALWAYS);
cr.renderGeometry(gl, c); cr.renderGeometry(gl, c);
gl.glDepthFunc(GL.GL_LESS); gl.glDepthFunc(GL.GL_LESS);
gl.glDepthRange(0, 1); gl.glDepthRange(0, 1);
}
} }
gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL); gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL);
gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GLLightingFunc.GL_EMISSION, gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GLLightingFunc.GL_EMISSION,