diff --git a/core/src/net/sf/openrocket/gui/figure3d/ComponentRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/ComponentRenderer.java index 80cdbfc02..57a592ce5 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/ComponentRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/ComponentRenderer.java @@ -33,55 +33,54 @@ public class ComponentRenderer { private static final LogHelper log = Application.getLogger(); private int LOD = 80; - + GLU glu; GLUquadric q; GLUtessellator tobj; - + public ComponentRenderer() { - + } - + public void init(GLAutoDrawable drawable) { glu = new GLU(); q = glu.gluNewQuadric(); tobj = GLU.gluNewTess(); glu.gluQuadricTexture(q, true); } - + private Map lists = new HashMap(); - private boolean clearDisplayLists = false; - public void updateFigure() { - clearDisplayLists = true; + + 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) { if (glu == null) throw new IllegalStateException(this + " Not Initialized"); - + glu.gluQuadricNormals(q, GLU.GLU_SMOOTH); - if ( clearDisplayLists ){ - log.debug("Clearing Display Lists"); - for ( int i : lists.values() ){ - gl.glDeleteLists(i,1); - } - lists.clear(); - clearDisplayLists = false; - } - if ( lists.containsKey(c) ){ + + if (lists.containsKey(c)) { gl.glCallList(lists.get(c)); } else { int list = gl.glGenLists(1); gl.glNewList(list, GL2.GL_COMPILE_AND_EXECUTE); - + Coordinate[] oo = c.toAbsolute(new Coordinate(0, 0, 0)); - + 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) { @@ -104,7 +103,7 @@ public class ComponentRenderer { lists.put(c, list); } } - + private void renderOther(GL2 gl, RocketComponent c) { gl.glBegin(GL.GL_LINES); for (Coordinate cc : c.getComponentBounds()) { @@ -115,92 +114,92 @@ public class ComponentRenderer { } gl.glEnd(); } - + private void renderTransition(GL2 gl, Transition t) { gl.glRotated(90, 0, 1.0, 0); - + if (t.getType() == Transition.Shape.CONICAL) { glu.gluCylinder(q, t.getForeRadius(), t.getAftRadius(), t.getLength(), LOD, 1); } else { TransitionRenderer.drawTransition(gl, t, LOD, LOD); } - + // Render AFT shoulder gl.glPushMatrix(); gl.glTranslated(0, 0, t.getLength()); - + glu.gluCylinder(q, t.getAftShoulderRadius(), t.getAftShoulderRadius(), t.getAftShoulderLength(), LOD, 1); - + gl.glRotated(180, 0, 1.0, 0); - + glu.gluDisk(q, t.getAftRadius(), t.getAftShoulderRadius(), LOD, 2); - + gl.glTranslated(0, 0, -t.getAftShoulderLength()); - + if (t.isFilled() || t.isAftShoulderCapped()) { glu.gluDisk(q, t.getAftShoulderRadius(), 0, LOD, 2); } gl.glPopMatrix(); - + // Render Fore Shoulder gl.glPushMatrix(); gl.glRotated(180, 0, 1.0, 0); - + glu.gluCylinder(q, t.getForeShoulderRadius(), t.getForeShoulderRadius(), t.getForeShoulderLength(), LOD, 1); - + gl.glRotated(180, 0, 1.0, 0); - + glu.gluDisk(q, t.getForeRadius(), t.getForeShoulderRadius(), LOD, 2); - + gl.glTranslated(0, 0, -t.getForeShoulderLength()); - + if (t.isFilled() || t.isForeShoulderCapped()) { glu.gluDisk(q, t.getForeShoulderRadius(), 0, LOD, 2); } gl.glPopMatrix(); - + } - + private void renderTube(GL2 gl, BodyTube t) { gl.glRotated(90, 0, 1.0, 0); glu.gluCylinder(q, t.getOuterRadius(), t.getOuterRadius(), t.getLength(), LOD, 1); } - + private void renderRing(GL2 gl, RingComponent r) { gl.glRotated(90, 0, 1.0, 0); glu.gluCylinder(q, r.getOuterRadius(), r.getOuterRadius(), r.getLength(), LOD, 1); - + gl.glRotated(180, 0, 1.0, 0); glu.gluDisk(q, r.getInnerRadius(), r.getOuterRadius(), LOD, 2); - + gl.glRotated(180, 0, 1.0, 0); gl.glTranslated(0, 0, r.getLength()); glu.gluDisk(q, r.getInnerRadius(), r.getOuterRadius(), LOD, 2); - + gl.glTranslated(0, 0, -r.getLength()); glu.gluCylinder(q, r.getInnerRadius(), r.getInnerRadius(), r.getLength(), LOD, 1); - + } - + private void renderLug(GL2 gl, LaunchLug t) { - + gl.glRotated(90, 0, 1.0, 0); glu.gluCylinder(q, t.getOuterRadius(), t.getOuterRadius(), t.getLength(), LOD, 1); } - + private void renderMassObject(GL2 gl, MassObject o) { gl.glRotated(90, 0, 1.0, 0); - + MassObjectRenderer.drawMassObject(gl, o, LOD, LOD); } - + private void renderFinSet(final GL2 gl, FinSet fs) { Coordinate finPoints[] = fs.getFinPointsWithTab(); @@ -209,31 +208,31 @@ public class ComponentRenderer { double minY = Double.MAX_VALUE; double maxX = Double.MIN_VALUE; double maxY = Double.MIN_VALUE; - + for (int i = 0; i < finPoints.length; i++) { Coordinate c = finPoints[i]; - minX = Math.min(c.x, minX); + minX = Math.min(c.x, minX); minY = Math.min(c.y, minY); maxX = Math.max(c.x, maxX); - maxY = Math.max(c.y, maxY); + maxY = Math.max(c.y, maxY); } gl.glMatrixMode(GL.GL_TEXTURE); gl.glPushMatrix(); - gl.glScaled(1/(maxX-minX), 1/(maxY-minY), 0); + gl.glScaled(1 / (maxX - minX), 1 / (maxY - minY), 0); gl.glTranslated(-minX, -minY - fs.getBodyRadius(), 0); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); gl.glRotated(fs.getBaseRotation() * (180.0 / Math.PI), 1, 0, 0); for (int fin = 0; fin < fs.getFinCount(); fin++) { - + gl.glPushMatrix(); - + gl.glTranslated(fs.getLength() / 2, 0, 0); gl.glRotated(fs.getCantAngle() * (180.0 / Math.PI), 0, 1, 0); gl.glTranslated(-fs.getLength() / 2, 0, 0); - + GLUtessellatorCallback cb = new GLUtessellatorCallbackAdapter() { @Override public void vertex(Object vertexData) { @@ -241,22 +240,22 @@ public class ComponentRenderer { gl.glTexCoord2d(d[0], d[1]); gl.glVertex3dv(d, 0); } - + @Override public void begin(int type) { gl.glBegin(type); } - + @Override public void end() { gl.glEnd(); } }; - + GLU.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, cb); GLU.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, cb); GLU.gluTessCallback(tobj, GLU.GLU_TESS_END, cb); - + GLU.gluTessBeginPolygon(tobj, null); GLU.gluTessBeginContour(tobj); gl.glNormal3f(0, 0, 1); @@ -265,11 +264,11 @@ public class ComponentRenderer { double[] p = new double[] { c.x, c.y + fs.getBodyRadius(), c.z + fs.getThickness() / 2.0 }; GLU.gluTessVertex(tobj, p, 0, p); - + } GLU.gluTessEndContour(tobj); GLU.gluTessEndPolygon(tobj); - + GLU.gluTessBeginPolygon(tobj, null); GLU.gluTessBeginContour(tobj); gl.glNormal3f(0, 0, -1); @@ -278,11 +277,11 @@ public class ComponentRenderer { double[] p = new double[] { c.x, c.y + fs.getBodyRadius(), c.z - fs.getThickness() / 2.0 }; GLU.gluTessVertex(tobj, p, 0, p); - + } GLU.gluTessEndContour(tobj); GLU.gluTessEndPolygon(tobj); - + // Strip around the edge if (!(fs instanceof EllipticalFinSet)) gl.glShadeModel(GLLightingFunc.GL_FLAT); @@ -303,9 +302,9 @@ public class ComponentRenderer { gl.glEnd(); if (!(fs instanceof EllipticalFinSet)) gl.glShadeModel(GLLightingFunc.GL_SMOOTH); - + gl.glPopMatrix(); - + gl.glRotated(360.0 / fs.getFinCount(), 1, 0, 0); } @@ -314,27 +313,27 @@ public class ComponentRenderer { gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); } - + public void renderMotor(final GL2 gl, final Coordinate c, double l, double r) { 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); - + gl.glPushMatrix(); - + gl.glTranslated(c.x, c.y, c.z); - + gl.glRotated(90, 0, 1.0, 0); - + glu.gluCylinder(q, r, r, l, LOD, 1); - + glu.gluDisk(q, r, 0, LOD, 2); - + gl.glTranslated(0, 0, l); gl.glRotated(180, 0, 1.0, 0); - + glu.gluDisk(q, r, 0, LOD, 2); - + gl.glPopMatrix(); } } diff --git a/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java index f3b9a9208..5bb27a385 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java @@ -28,7 +28,6 @@ public class RealisticRenderer extends RocketRenderer { private final float[] colorWhite = { 1, 1, 1, 1 }; private final float[] color = new float[4]; - private boolean needClearCache = false; private Map oldTexCache = new HashMap(); private Map texCache = new HashMap(); private float anisotrophy = 0; @@ -69,10 +68,9 @@ public class RealisticRenderer extends RocketRenderer { } @Override - public void updateFigure() { - super.updateFigure(); - - needClearCache = true; + public void updateFigure(GLAutoDrawable drawable) { + super.updateFigure(drawable); + clearCaches(drawable.getGL().getGL2()); } @Override @@ -95,12 +93,6 @@ public class RealisticRenderer extends RocketRenderer { @Override public void renderComponent(GL2 gl, RocketComponent c, float alpha) { - - if (needClearCache) { - clearCaches(gl); - needClearCache = false; - } - final Appearance a = getAppearance(c); final Decal t = a.getTexture(); final Texture tex = getTexture(t); diff --git a/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java b/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java index 8b3f558a0..e5f13f322 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java +++ b/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java @@ -518,8 +518,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener { public void updateFigure() { log.debug("3D Figure Updated"); cachedBounds = null; - rr.updateFigure(); - internalRepaint(); + canvas.invoke(true, new GLRunnable() { + @Override + public boolean run(GLAutoDrawable drawable) { + rr.updateFigure(drawable); + return false; + } + }); } private void internalRepaint() { diff --git a/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java b/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java index 959908620..3da885fed 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java +++ b/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java @@ -38,8 +38,8 @@ public abstract class RocketRenderer { public void dispose(GLAutoDrawable drawable) { } - public void updateFigure() { - cr.updateFigure(); + public void updateFigure(GLAutoDrawable drawable) { + cr.updateFigure(drawable); } public abstract void renderComponent(GL2 gl, RocketComponent c, float alpha);