diff --git a/core/src/net/sf/openrocket/gui/figure3d/FigureRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/FigureRenderer.java index dbacece61..e8b0d03bf 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/FigureRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/FigureRenderer.java @@ -8,6 +8,7 @@ import javax.media.opengl.GL2ES1; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.fixedfunc.GLLightingFunc; +import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.ExternalComponent; @@ -17,7 +18,6 @@ import net.sf.openrocket.rocketcomponent.SymmetricComponent; import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.Color; -import net.sf.openrocket.util.Coordinate; public class FigureRenderer extends RocketRenderer { private final float[] color = new float[4]; @@ -120,7 +120,7 @@ public class FigureRenderer extends RocketRenderer { gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_DIFFUSE, color, 0); gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_AMBIENT, color, 0); - cr.renderGeometry(gl, c); + cr.getGeometry(c, Surface.OUTSIDE).render(gl); } @Override @@ -161,10 +161,10 @@ public class FigureRenderer extends RocketRenderer { @Override - protected void renderMotor(GL2 gl, Coordinate c, Motor motor) { + protected void renderMotor(GL2 gl, Motor motor) { final float outside[] = { 0.2f, 0.2f, 0.2f, 1.0f }; gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_DIFFUSE, outside, 0); gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, outside, 0); - super.renderMotor(gl, c, motor); + super.renderMotor(gl, motor); } } diff --git a/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java index 257778fff..9c291d227 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java @@ -16,10 +16,11 @@ import net.sf.openrocket.appearance.Appearance; import net.sf.openrocket.appearance.Decal; import net.sf.openrocket.appearance.defaults.DefaultAppearance; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.figure3d.geometry.Geometry; +import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.util.Color; -import net.sf.openrocket.util.Coordinate; import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.TextureData; @@ -95,26 +96,18 @@ public class RealisticRenderer extends RocketRenderer { } @Override - protected void renderMotor(final GL2 gl, final Coordinate c, final Motor motor) { - render(gl, new Runnable() { - @Override - public void run() { - cr.renderMotor(gl, c, motor); - } - }, DefaultAppearance.getDefaultAppearance(motor), 1); + protected void renderMotor(final GL2 gl, final Motor motor) { + render(gl, cr.getGeometry(motor, Surface.OUTSIDE), DefaultAppearance.getDefaultAppearance(motor), true, 1); } @Override public void renderComponent(final GL2 gl, final RocketComponent c, final float alpha) { - render(gl, new Runnable() { - @Override - public void run() { - cr.renderGeometry(gl, c); - } - }, getAppearance(c), alpha); + render(gl, cr.getGeometry(c, Surface.OUTSIDE), getAppearance(c), true, alpha); + render(gl, cr.getGeometry(c, Surface.EDGES), getAppearance(c), false, alpha); + render(gl, cr.getGeometry(c, Surface.INSIDE), DefaultAppearance.getDefaultAppearance(c), true, alpha); } - private void render(GL2 gl, Runnable g, Appearance a, float alpha) { + private void render(GL2 gl, Geometry g, Appearance a, boolean decals, float alpha) { final Decal t = a.getTexture(); final Texture tex = getTexture(t); @@ -137,9 +130,9 @@ public class RealisticRenderer extends RocketRenderer { gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_SPECULAR, colorBlack, 0); gl.glMateriali(GL.GL_BACK, GLLightingFunc.GL_SHININESS, 0); - g.run(); + g.render(gl); - if (t != null && tex != null) { + if (decals && t != null && tex != null) { gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); @@ -176,7 +169,7 @@ public class RealisticRenderer extends RocketRenderer { gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotrophy); } - g.run(); + g.render(gl); if (t.getEdgeMode() == Decal.EdgeMode.STICKER) { gl.glDepthFunc(GL.GL_LESS); diff --git a/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java index dc2b5c449..4c7cd083b 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java @@ -12,6 +12,8 @@ import javax.media.opengl.GL2GL3; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.fixedfunc.GLLightingFunc; +import net.sf.openrocket.gui.figure3d.geometry.ComponentRenderer; +import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.Configuration; @@ -73,10 +75,10 @@ public abstract class RocketRenderer { if (isDrawnTransparent(c)) { gl.glEnable(GL.GL_CULL_FACE); gl.glCullFace(GL.GL_FRONT); - cr.renderGeometry(gl, c); + cr.getGeometry(c, Surface.OUTSIDE).render(gl); gl.glDisable(GL.GL_CULL_FACE); } else { - cr.renderGeometry(gl, c); + cr.getGeometry(c, Surface.OUTSIDE).render(gl); } } @@ -115,14 +117,14 @@ public abstract class RocketRenderer { // Draw as lines, set Z to nearest gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_LINE); gl.glDepthRange(0, 0); - cr.renderGeometry(gl, c); + cr.getGeometry(c, Surface.OUTSIDE).render(gl); // Draw polygons, always passing depth test, // setting Z to farthest gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL); gl.glDepthRange(1, 1); gl.glDepthFunc(GL.GL_ALWAYS); - cr.renderGeometry(gl, c); + cr.getGeometry(c, Surface.OUTSIDE).render(gl); gl.glDepthFunc(GL.GL_LESS); gl.glDepthRange(0, 1); } @@ -183,14 +185,17 @@ public abstract class RocketRenderer { .getLength() + mount.getMotorOverhang() - length)); for (int i = 0; i < position.length; i++) { - renderMotor(gl, position[i], motor); + gl.glPushMatrix(); + gl.glTranslated(position[i].x, position[i].y, position[i].z); + renderMotor(gl, motor); + gl.glPopMatrix(); } } } - protected void renderMotor(GL2 gl, Coordinate c, Motor motor) { - cr.renderMotor(gl, c, motor); + protected void renderMotor(GL2 gl, Motor motor) { + cr.getGeometry(motor, Surface.OUTSIDE).render(gl); } } diff --git a/core/src/net/sf/openrocket/gui/figure3d/ComponentRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java similarity index 77% rename from core/src/net/sf/openrocket/gui/figure3d/ComponentRenderer.java rename to core/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java index 1a2434049..c43befc77 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/ComponentRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java @@ -1,7 +1,4 @@ -package net.sf.openrocket.gui.figure3d; - -import java.util.HashMap; -import java.util.Map; +package net.sf.openrocket.gui.figure3d.geometry; import javax.media.opengl.GL; import javax.media.opengl.GL2; @@ -14,6 +11,7 @@ import javax.media.opengl.glu.GLUtessellator; import javax.media.opengl.glu.GLUtessellatorCallback; import javax.media.opengl.glu.GLUtessellatorCallbackAdapter; +import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.BodyTube; @@ -31,6 +29,7 @@ import net.sf.openrocket.util.Coordinate; * @author Bill Kuker */ public class ComponentRenderer { + @SuppressWarnings("unused") private static final LogHelper log = Application.getLogger(); private int LOD = 80; @@ -50,59 +49,62 @@ public class ComponentRenderer { glu.gluQuadricTexture(q, true); } - private Map lists = new HashMap(); public void updateFigure(GLAutoDrawable drawable) { - log.debug("Clearing Display Lists"); - GL2 gl = drawable.getGL().getGL2(); - for (int i : lists.values()) { - gl.glDeleteLists(i, 1); - } - lists.clear(); } - public void renderGeometry(GL2 gl, RocketComponent c) { + public Geometry getGeometry(final RocketComponent c, final Surface which) { + return new Geometry() { + + @Override + public void render(GL2 gl) { + renderGeometry(gl, c, which); + } + + }; + } + + public Geometry getGeometry(final Motor motor, Surface which) { + return new Geometry() { + @Override + public void render(GL2 gl) { + renderMotor(gl, motor); + } + }; + } + + private void renderGeometry(GL2 gl, RocketComponent c, Surface which) { if (glu == null) throw new IllegalStateException(this + " Not Initialized"); glu.gluQuadricNormals(q, GLU.GLU_SMOOTH); + Coordinate[] oo = c.toAbsolute(new Coordinate(0, 0, 0)); - if (lists.containsKey(c)) { - gl.glCallList(lists.get(c)); - } else { - int list = gl.glGenLists(1); - gl.glNewList(list, GL2.GL_COMPILE_AND_EXECUTE); + for (Coordinate o : oo) { + gl.glPushMatrix(); - Coordinate[] oo = c.toAbsolute(new Coordinate(0, 0, 0)); + gl.glTranslated(o.x, o.y, o.z); - for (Coordinate o : oo) { - gl.glPushMatrix(); - - gl.glTranslated(o.x, o.y, o.z); - - if (c instanceof BodyTube) { - renderTube(gl, (BodyTube) c); - } else if (c instanceof LaunchLug) { - renderLug(gl, (LaunchLug) c); - } else if (c instanceof RingComponent) { - renderRing(gl, (RingComponent) c); - } else if (c instanceof Transition) { - renderTransition(gl, (Transition) c); - } else if (c instanceof MassObject) { - renderMassObject(gl, (MassObject) c); - } else if (c instanceof FinSet) { - renderFinSet(gl, (FinSet) c); - } else { - renderOther(gl, c); - } - gl.glPopMatrix(); + if (c instanceof BodyTube) { + renderTube(gl, (BodyTube) c, which); + } else if (c instanceof LaunchLug) { + renderLug(gl, (LaunchLug) c); + } else if (c instanceof RingComponent) { + renderRing(gl, (RingComponent) c); + } else if (c instanceof Transition) { + renderTransition(gl, (Transition) c); + } else if (c instanceof MassObject) { + renderMassObject(gl, (MassObject) c); + } else if (c instanceof FinSet) { + renderFinSet(gl, (FinSet) c); + } else { + renderOther(gl, c); } - - gl.glEndList(); - lists.put(c, list); + gl.glPopMatrix(); } + } private void renderOther(GL2 gl, RocketComponent c) { @@ -164,10 +166,32 @@ public class ComponentRenderer { } - private void renderTube(GL2 gl, BodyTube t) { + private void renderTube(GL2 gl, BodyTube t, Surface which) { + //TODO REfactor without the extra transforms + + //outside gl.glRotated(90, 0, 1.0, 0); - glu.gluCylinder(q, t.getOuterRadius(), t.getOuterRadius(), - t.getLength(), LOD, 1); + if (which == Surface.OUTSIDE) + glu.gluCylinder(q, t.getOuterRadius(), t.getOuterRadius(), + t.getLength(), LOD, 1); + + //edges + gl.glRotated(180, 0, 1.0, 0); + if (which == Surface.EDGES) + glu.gluDisk(q, t.getInnerRadius(), t.getOuterRadius(), LOD, 2); + + gl.glRotated(180, 0, 1.0, 0); + gl.glTranslated(0, 0, t.getLength()); + if (which == Surface.EDGES) + glu.gluDisk(q, t.getInnerRadius(), t.getOuterRadius(), LOD, 2); + + + //inside + gl.glTranslated(0, 0, -t.getLength()); + if (which == Surface.INSIDE) + glu.gluCylinder(q, t.getInnerRadius(), t.getInnerRadius(), + t.getLength(), LOD, 1); + } private void renderRing(GL2 gl, RingComponent r) { @@ -315,14 +339,12 @@ public class ComponentRenderer { } - public void renderMotor(final GL2 gl, final Coordinate c, Motor motor) { + private void renderMotor(final GL2 gl, Motor motor) { double l = motor.getLength(); double r = motor.getDiameter() / 2; gl.glPushMatrix(); - gl.glTranslated(c.x, c.y, c.z); - gl.glRotated(90, 0, 1.0, 0); gl.glMatrixMode(GL.GL_TEXTURE); diff --git a/core/src/net/sf/openrocket/gui/figure3d/geometry/Geometry.java b/core/src/net/sf/openrocket/gui/figure3d/geometry/Geometry.java new file mode 100644 index 000000000..f898e268f --- /dev/null +++ b/core/src/net/sf/openrocket/gui/figure3d/geometry/Geometry.java @@ -0,0 +1,11 @@ +package net.sf.openrocket.gui.figure3d.geometry; + +import javax.media.opengl.GL2; + +public interface Geometry { + public static enum Surface { + OUTSIDE, INSIDE, EDGES; + } + + public void render(GL2 gl); +} diff --git a/core/src/net/sf/openrocket/gui/figure3d/MassObjectRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/geometry/MassObjectRenderer.java similarity index 95% rename from core/src/net/sf/openrocket/gui/figure3d/MassObjectRenderer.java rename to core/src/net/sf/openrocket/gui/figure3d/geometry/MassObjectRenderer.java index 4c1d93443..387c8c93d 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/MassObjectRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/geometry/MassObjectRenderer.java @@ -112,31 +112,31 @@ * in the design, construction, operation or maintenance of any nuclear * facility. */ -package net.sf.openrocket.gui.figure3d; +package net.sf.openrocket.gui.figure3d.geometry; import javax.media.opengl.GL; import javax.media.opengl.GL2; import net.sf.openrocket.rocketcomponent.MassObject; -public final class MassObjectRenderer { +final class MassObjectRenderer { private static final boolean textureFlag = true; - + private MassObjectRenderer() { } - - public static final void drawMassObject(final GL2 gl, final MassObject o, + + static final void drawMassObject(final GL2 gl, final MassObject o, final int slices, final int stacks) { - + double da, r, dz; double x, y, z, nz, nsign; int i, j; - + nsign = 1.0f; - + da = 2.0f * PI / slices; dz = o.getLength() / stacks; - + double ds = 1.0f / slices; double dt = 1.0f / stacks; double t = 0.0f; @@ -146,13 +146,13 @@ public final class MassObjectRenderer { double rNext = getRadius(o, z + dz); if (j == stacks - 1) rNext = 0; - + if (j == stacks - 1) rNext = 0; - + // Z component of normal vectors nz = -(rNext - r) / dz; - + double s = 0.0f; glBegin(gl, GL2.GL_QUAD_STRIP); for (i = 0; i <= slices; i++) { @@ -186,7 +186,7 @@ public final class MassObjectRenderer { z += dz; } // for stacks } - + private static final double getRadius(MassObject o, double z) { double arc = Math.min(o.getLength(), 2 * o.getRadius()) * 0.35f; double r = o.getRadius(); @@ -202,33 +202,33 @@ public final class MassObjectRenderer { } return o.getRadius(); } - + // ---------------------------------------------------------------------- // Internals only below this point // - + private static final double PI = Math.PI; - + private static final void glBegin(GL gl, int mode) { gl.getGL2().glBegin(mode); } - + private static final void glEnd(GL gl) { gl.getGL2().glEnd(); } - + private static final void glVertex3d(GL gl, double x, double y, double z) { gl.getGL2().glVertex3d(x, y, z); } - + private static final void glNormal3d(GL gl, double x, double y, double z) { gl.getGL2().glNormal3d(x, y, z); } - + private static final void glTexCoord2d(GL gl, double x, double y) { gl.getGL2().glTexCoord2d(x, y); } - + /** * Call glNormal3f after scaling normal to unit length. * @@ -238,7 +238,7 @@ public final class MassObjectRenderer { */ private static final void normal3d(GL gl, double x, double y, double z) { double mag; - + mag = Math.sqrt(x * x + y * y + z * z); if (mag > 0.00001F) { x /= mag; @@ -247,16 +247,16 @@ public final class MassObjectRenderer { } glNormal3d(gl, x, y, z); } - + private static final void TXTR_COORD(GL gl, double x, double y) { if (textureFlag) glTexCoord2d(gl, x, y); } - + private static final double sin(double r) { return Math.sin(r); } - + private static final double cos(double r) { return Math.cos(r); } diff --git a/core/src/net/sf/openrocket/gui/figure3d/TransitionRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/geometry/TransitionRenderer.java similarity index 95% rename from core/src/net/sf/openrocket/gui/figure3d/TransitionRenderer.java rename to core/src/net/sf/openrocket/gui/figure3d/geometry/TransitionRenderer.java index 3789a7809..9dbcc9900 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/TransitionRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/geometry/TransitionRenderer.java @@ -112,31 +112,31 @@ * in the design, construction, operation or maintenance of any nuclear * facility. */ -package net.sf.openrocket.gui.figure3d; +package net.sf.openrocket.gui.figure3d.geometry; import javax.media.opengl.GL; import javax.media.opengl.GL2; import net.sf.openrocket.rocketcomponent.Transition; -public final class TransitionRenderer { +final class TransitionRenderer { private static final boolean textureFlag = true; - + private TransitionRenderer() { } - - public static final void drawTransition(final GL2 gl, final Transition tr, + + static final void drawTransition(final GL2 gl, final Transition tr, final int slices, final int stacks) { - + double da, r, dz; double x, y, z, nz, nsign; int i, j; - + nsign = 1.0f; - + da = 2.0f * PI / slices; dz = (double) tr.getLength() / stacks; - + double ds = 1.0f / slices; double dt = 1.0f / stacks; double t = 0.0f; @@ -145,13 +145,13 @@ public final class TransitionRenderer { for (j = 0; j < stacks; j++) { r = (double) tr.getRadius(z); double rNext = (double) tr.getRadius(z + dz); - + if (j == stacks - 1) rNext = (double) tr.getRadius(tr.getLength()); - + // Z component of normal vectors nz = -(rNext - r) / dz; - + double s = 0.0f; glBegin(gl, GL2.GL_QUAD_STRIP); for (i = 0; i <= slices; i++) { @@ -184,35 +184,35 @@ public final class TransitionRenderer { t += dt; z += dz; } // for stacks - + } - + // ---------------------------------------------------------------------- // Internals only below this point // - + private static final double PI = (double) Math.PI; - + private static final void glBegin(GL gl, int mode) { gl.getGL2().glBegin(mode); } - + private static final void glEnd(GL gl) { gl.getGL2().glEnd(); } - + private static final void glVertex3d(GL gl, double x, double y, double z) { gl.getGL2().glVertex3d(x, y, z); } - + private static final void glNormal3d(GL gl, double x, double y, double z) { gl.getGL2().glNormal3d(x, y, z); } - + private static final void glTexCoord2d(GL gl, double x, double y) { gl.getGL2().glTexCoord2d(x, y); } - + /** * Call glNormal3f after scaling normal to unit length. * @@ -222,7 +222,7 @@ public final class TransitionRenderer { */ private static final void normal3d(GL gl, double x, double y, double z) { double mag; - + mag = (double) Math.sqrt(x * x + y * y + z * z); if (mag > 0.00001F) { x /= mag; @@ -231,16 +231,16 @@ public final class TransitionRenderer { } glNormal3d(gl, x, y, z); } - + private static final void TXTR_COORD(GL gl, double x, double y) { if (textureFlag) glTexCoord2d(gl, x, y); } - + private static final double sin(double r) { return (double) Math.sin(r); } - + private static final double cos(double r) { return (double) Math.cos(r); }