Simplify the RocketFigure3D updateFigure() method to take advantage of

JOGL's invoke & GLRunnable, rather than using flags, to simplify the
code.
This commit is contained in:
bkuker 2013-01-08 10:05:45 -05:00
parent fa58cb6338
commit f6358ad2ba
4 changed files with 86 additions and 90 deletions

View File

@ -33,55 +33,54 @@ public class ComponentRenderer {
private static final LogHelper log = Application.getLogger(); private static final LogHelper log = Application.getLogger();
private int LOD = 80; private int LOD = 80;
GLU glu; GLU glu;
GLUquadric q; GLUquadric q;
GLUtessellator tobj; GLUtessellator tobj;
public ComponentRenderer() { public ComponentRenderer() {
} }
public void init(GLAutoDrawable drawable) { public void init(GLAutoDrawable drawable) {
glu = new GLU(); glu = new GLU();
q = glu.gluNewQuadric(); q = glu.gluNewQuadric();
tobj = GLU.gluNewTess(); tobj = GLU.gluNewTess();
glu.gluQuadricTexture(q, true); glu.gluQuadricTexture(q, true);
} }
private Map<RocketComponent, Integer> lists = new HashMap<RocketComponent, Integer>(); private Map<RocketComponent, Integer> lists = new HashMap<RocketComponent, Integer>();
private boolean clearDisplayLists = false;
public void updateFigure() { public void updateFigure(GLAutoDrawable drawable) {
clearDisplayLists = true; 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 void renderGeometry(GL2 gl, RocketComponent c) {
if (glu == null) if (glu == null)
throw new IllegalStateException(this + " Not Initialized"); throw new IllegalStateException(this + " Not Initialized");
glu.gluQuadricNormals(q, GLU.GLU_SMOOTH); glu.gluQuadricNormals(q, GLU.GLU_SMOOTH);
if ( clearDisplayLists ){
log.debug("Clearing Display Lists"); if (lists.containsKey(c)) {
for ( int i : lists.values() ){
gl.glDeleteLists(i,1);
}
lists.clear();
clearDisplayLists = false;
}
if ( lists.containsKey(c) ){
gl.glCallList(lists.get(c)); gl.glCallList(lists.get(c));
} else { } else {
int list = gl.glGenLists(1); int list = gl.glGenLists(1);
gl.glNewList(list, GL2.GL_COMPILE_AND_EXECUTE); gl.glNewList(list, GL2.GL_COMPILE_AND_EXECUTE);
Coordinate[] oo = c.toAbsolute(new Coordinate(0, 0, 0)); Coordinate[] oo = c.toAbsolute(new Coordinate(0, 0, 0));
for (Coordinate o : oo) { for (Coordinate o : oo) {
gl.glPushMatrix(); gl.glPushMatrix();
gl.glTranslated(o.x, o.y, o.z); gl.glTranslated(o.x, o.y, o.z);
if (c instanceof BodyTube) { if (c instanceof BodyTube) {
renderTube(gl, (BodyTube) c); renderTube(gl, (BodyTube) c);
} else if (c instanceof LaunchLug) { } else if (c instanceof LaunchLug) {
@ -104,7 +103,7 @@ public class ComponentRenderer {
lists.put(c, list); lists.put(c, list);
} }
} }
private void renderOther(GL2 gl, RocketComponent c) { private void renderOther(GL2 gl, RocketComponent c) {
gl.glBegin(GL.GL_LINES); gl.glBegin(GL.GL_LINES);
for (Coordinate cc : c.getComponentBounds()) { for (Coordinate cc : c.getComponentBounds()) {
@ -115,92 +114,92 @@ public class ComponentRenderer {
} }
gl.glEnd(); gl.glEnd();
} }
private void renderTransition(GL2 gl, Transition t) { private void renderTransition(GL2 gl, Transition t) {
gl.glRotated(90, 0, 1.0, 0); gl.glRotated(90, 0, 1.0, 0);
if (t.getType() == Transition.Shape.CONICAL) { if (t.getType() == Transition.Shape.CONICAL) {
glu.gluCylinder(q, t.getForeRadius(), t.getAftRadius(), glu.gluCylinder(q, t.getForeRadius(), t.getAftRadius(),
t.getLength(), LOD, 1); t.getLength(), LOD, 1);
} else { } else {
TransitionRenderer.drawTransition(gl, t, LOD, LOD); TransitionRenderer.drawTransition(gl, t, LOD, LOD);
} }
// Render AFT shoulder // Render AFT shoulder
gl.glPushMatrix(); gl.glPushMatrix();
gl.glTranslated(0, 0, t.getLength()); gl.glTranslated(0, 0, t.getLength());
glu.gluCylinder(q, t.getAftShoulderRadius(), t.getAftShoulderRadius(), glu.gluCylinder(q, t.getAftShoulderRadius(), t.getAftShoulderRadius(),
t.getAftShoulderLength(), LOD, 1); t.getAftShoulderLength(), LOD, 1);
gl.glRotated(180, 0, 1.0, 0); gl.glRotated(180, 0, 1.0, 0);
glu.gluDisk(q, t.getAftRadius(), t.getAftShoulderRadius(), LOD, 2); glu.gluDisk(q, t.getAftRadius(), t.getAftShoulderRadius(), LOD, 2);
gl.glTranslated(0, 0, -t.getAftShoulderLength()); gl.glTranslated(0, 0, -t.getAftShoulderLength());
if (t.isFilled() || t.isAftShoulderCapped()) { if (t.isFilled() || t.isAftShoulderCapped()) {
glu.gluDisk(q, t.getAftShoulderRadius(), 0, LOD, 2); glu.gluDisk(q, t.getAftShoulderRadius(), 0, LOD, 2);
} }
gl.glPopMatrix(); gl.glPopMatrix();
// Render Fore Shoulder // Render Fore Shoulder
gl.glPushMatrix(); gl.glPushMatrix();
gl.glRotated(180, 0, 1.0, 0); gl.glRotated(180, 0, 1.0, 0);
glu.gluCylinder(q, t.getForeShoulderRadius(), glu.gluCylinder(q, t.getForeShoulderRadius(),
t.getForeShoulderRadius(), t.getForeShoulderLength(), LOD, 1); t.getForeShoulderRadius(), t.getForeShoulderLength(), LOD, 1);
gl.glRotated(180, 0, 1.0, 0); gl.glRotated(180, 0, 1.0, 0);
glu.gluDisk(q, t.getForeRadius(), t.getForeShoulderRadius(), LOD, 2); glu.gluDisk(q, t.getForeRadius(), t.getForeShoulderRadius(), LOD, 2);
gl.glTranslated(0, 0, -t.getForeShoulderLength()); gl.glTranslated(0, 0, -t.getForeShoulderLength());
if (t.isFilled() || t.isForeShoulderCapped()) { if (t.isFilled() || t.isForeShoulderCapped()) {
glu.gluDisk(q, t.getForeShoulderRadius(), 0, LOD, 2); glu.gluDisk(q, t.getForeShoulderRadius(), 0, LOD, 2);
} }
gl.glPopMatrix(); gl.glPopMatrix();
} }
private void renderTube(GL2 gl, BodyTube t) { private void renderTube(GL2 gl, BodyTube t) {
gl.glRotated(90, 0, 1.0, 0); gl.glRotated(90, 0, 1.0, 0);
glu.gluCylinder(q, t.getOuterRadius(), t.getOuterRadius(), glu.gluCylinder(q, t.getOuterRadius(), t.getOuterRadius(),
t.getLength(), LOD, 1); t.getLength(), LOD, 1);
} }
private void renderRing(GL2 gl, RingComponent r) { private void renderRing(GL2 gl, RingComponent r) {
gl.glRotated(90, 0, 1.0, 0); gl.glRotated(90, 0, 1.0, 0);
glu.gluCylinder(q, r.getOuterRadius(), r.getOuterRadius(), glu.gluCylinder(q, r.getOuterRadius(), r.getOuterRadius(),
r.getLength(), LOD, 1); r.getLength(), LOD, 1);
gl.glRotated(180, 0, 1.0, 0); gl.glRotated(180, 0, 1.0, 0);
glu.gluDisk(q, r.getInnerRadius(), r.getOuterRadius(), LOD, 2); glu.gluDisk(q, r.getInnerRadius(), r.getOuterRadius(), LOD, 2);
gl.glRotated(180, 0, 1.0, 0); gl.glRotated(180, 0, 1.0, 0);
gl.glTranslated(0, 0, r.getLength()); gl.glTranslated(0, 0, r.getLength());
glu.gluDisk(q, r.getInnerRadius(), r.getOuterRadius(), LOD, 2); glu.gluDisk(q, r.getInnerRadius(), r.getOuterRadius(), LOD, 2);
gl.glTranslated(0, 0, -r.getLength()); gl.glTranslated(0, 0, -r.getLength());
glu.gluCylinder(q, r.getInnerRadius(), r.getInnerRadius(), glu.gluCylinder(q, r.getInnerRadius(), r.getInnerRadius(),
r.getLength(), LOD, 1); r.getLength(), LOD, 1);
} }
private void renderLug(GL2 gl, LaunchLug t) { private void renderLug(GL2 gl, LaunchLug t) {
gl.glRotated(90, 0, 1.0, 0); gl.glRotated(90, 0, 1.0, 0);
glu.gluCylinder(q, t.getOuterRadius(), t.getOuterRadius(), glu.gluCylinder(q, t.getOuterRadius(), t.getOuterRadius(),
t.getLength(), LOD, 1); t.getLength(), LOD, 1);
} }
private void renderMassObject(GL2 gl, MassObject o) { private void renderMassObject(GL2 gl, MassObject o) {
gl.glRotated(90, 0, 1.0, 0); gl.glRotated(90, 0, 1.0, 0);
MassObjectRenderer.drawMassObject(gl, o, LOD, LOD); MassObjectRenderer.drawMassObject(gl, o, LOD, LOD);
} }
private void renderFinSet(final GL2 gl, FinSet fs) { private void renderFinSet(final GL2 gl, FinSet fs) {
Coordinate finPoints[] = fs.getFinPointsWithTab(); Coordinate finPoints[] = fs.getFinPointsWithTab();
@ -209,31 +208,31 @@ public class ComponentRenderer {
double minY = Double.MAX_VALUE; double minY = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE; double maxX = Double.MIN_VALUE;
double maxY = Double.MIN_VALUE; double maxY = Double.MIN_VALUE;
for (int i = 0; i < finPoints.length; i++) { for (int i = 0; i < finPoints.length; i++) {
Coordinate c = finPoints[i]; Coordinate c = finPoints[i];
minX = Math.min(c.x, minX); minX = Math.min(c.x, minX);
minY = Math.min(c.y, minY); minY = Math.min(c.y, minY);
maxX = Math.max(c.x, maxX); maxX = Math.max(c.x, maxX);
maxY = Math.max(c.y, maxY); maxY = Math.max(c.y, maxY);
} }
gl.glMatrixMode(GL.GL_TEXTURE); gl.glMatrixMode(GL.GL_TEXTURE);
gl.glPushMatrix(); 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.glTranslated(-minX, -minY - fs.getBodyRadius(), 0);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glRotated(fs.getBaseRotation() * (180.0 / Math.PI), 1, 0, 0); gl.glRotated(fs.getBaseRotation() * (180.0 / Math.PI), 1, 0, 0);
for (int fin = 0; fin < fs.getFinCount(); fin++) { for (int fin = 0; fin < fs.getFinCount(); fin++) {
gl.glPushMatrix(); gl.glPushMatrix();
gl.glTranslated(fs.getLength() / 2, 0, 0); gl.glTranslated(fs.getLength() / 2, 0, 0);
gl.glRotated(fs.getCantAngle() * (180.0 / Math.PI), 0, 1, 0); gl.glRotated(fs.getCantAngle() * (180.0 / Math.PI), 0, 1, 0);
gl.glTranslated(-fs.getLength() / 2, 0, 0); gl.glTranslated(-fs.getLength() / 2, 0, 0);
GLUtessellatorCallback cb = new GLUtessellatorCallbackAdapter() { GLUtessellatorCallback cb = new GLUtessellatorCallbackAdapter() {
@Override @Override
public void vertex(Object vertexData) { public void vertex(Object vertexData) {
@ -241,22 +240,22 @@ public class ComponentRenderer {
gl.glTexCoord2d(d[0], d[1]); gl.glTexCoord2d(d[0], d[1]);
gl.glVertex3dv(d, 0); gl.glVertex3dv(d, 0);
} }
@Override @Override
public void begin(int type) { public void begin(int type) {
gl.glBegin(type); gl.glBegin(type);
} }
@Override @Override
public void end() { public void end() {
gl.glEnd(); gl.glEnd();
} }
}; };
GLU.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, cb); GLU.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, cb);
GLU.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, cb); GLU.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, cb);
GLU.gluTessCallback(tobj, GLU.GLU_TESS_END, cb); GLU.gluTessCallback(tobj, GLU.GLU_TESS_END, cb);
GLU.gluTessBeginPolygon(tobj, null); GLU.gluTessBeginPolygon(tobj, null);
GLU.gluTessBeginContour(tobj); GLU.gluTessBeginContour(tobj);
gl.glNormal3f(0, 0, 1); gl.glNormal3f(0, 0, 1);
@ -265,11 +264,11 @@ public class ComponentRenderer {
double[] p = new double[] { c.x, c.y + fs.getBodyRadius(), double[] p = new double[] { c.x, c.y + fs.getBodyRadius(),
c.z + fs.getThickness() / 2.0 }; c.z + fs.getThickness() / 2.0 };
GLU.gluTessVertex(tobj, p, 0, p); GLU.gluTessVertex(tobj, p, 0, p);
} }
GLU.gluTessEndContour(tobj); GLU.gluTessEndContour(tobj);
GLU.gluTessEndPolygon(tobj); GLU.gluTessEndPolygon(tobj);
GLU.gluTessBeginPolygon(tobj, null); GLU.gluTessBeginPolygon(tobj, null);
GLU.gluTessBeginContour(tobj); GLU.gluTessBeginContour(tobj);
gl.glNormal3f(0, 0, -1); gl.glNormal3f(0, 0, -1);
@ -278,11 +277,11 @@ public class ComponentRenderer {
double[] p = new double[] { c.x, c.y + fs.getBodyRadius(), double[] p = new double[] { c.x, c.y + fs.getBodyRadius(),
c.z - fs.getThickness() / 2.0 }; c.z - fs.getThickness() / 2.0 };
GLU.gluTessVertex(tobj, p, 0, p); GLU.gluTessVertex(tobj, p, 0, p);
} }
GLU.gluTessEndContour(tobj); GLU.gluTessEndContour(tobj);
GLU.gluTessEndPolygon(tobj); GLU.gluTessEndPolygon(tobj);
// Strip around the edge // Strip around the edge
if (!(fs instanceof EllipticalFinSet)) if (!(fs instanceof EllipticalFinSet))
gl.glShadeModel(GLLightingFunc.GL_FLAT); gl.glShadeModel(GLLightingFunc.GL_FLAT);
@ -303,9 +302,9 @@ public class ComponentRenderer {
gl.glEnd(); gl.glEnd();
if (!(fs instanceof EllipticalFinSet)) if (!(fs instanceof EllipticalFinSet))
gl.glShadeModel(GLLightingFunc.GL_SMOOTH); gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
gl.glPopMatrix(); gl.glPopMatrix();
gl.glRotated(360.0 / fs.getFinCount(), 1, 0, 0); gl.glRotated(360.0 / fs.getFinCount(), 1, 0, 0);
} }
@ -314,27 +313,27 @@ public class ComponentRenderer {
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
} }
public void renderMotor(final GL2 gl, final Coordinate c, double l, double r) { public void renderMotor(final GL2 gl, final Coordinate c, double l, double r) {
final float outside[] = { 0.2f, 0.2f, 0.2f, 1.0f }; 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_DIFFUSE, outside, 0);
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, outside, 0); gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, outside, 0);
gl.glPushMatrix(); gl.glPushMatrix();
gl.glTranslated(c.x, c.y, c.z); gl.glTranslated(c.x, c.y, c.z);
gl.glRotated(90, 0, 1.0, 0); gl.glRotated(90, 0, 1.0, 0);
glu.gluCylinder(q, r, r, l, LOD, 1); glu.gluCylinder(q, r, r, l, LOD, 1);
glu.gluDisk(q, r, 0, LOD, 2); glu.gluDisk(q, r, 0, LOD, 2);
gl.glTranslated(0, 0, l); gl.glTranslated(0, 0, l);
gl.glRotated(180, 0, 1.0, 0); gl.glRotated(180, 0, 1.0, 0);
glu.gluDisk(q, r, 0, LOD, 2); glu.gluDisk(q, r, 0, LOD, 2);
gl.glPopMatrix(); gl.glPopMatrix();
} }
} }

View File

@ -28,7 +28,6 @@ public class RealisticRenderer extends RocketRenderer {
private final float[] colorWhite = { 1, 1, 1, 1 }; private final float[] colorWhite = { 1, 1, 1, 1 };
private final float[] color = new float[4]; private final float[] color = new float[4];
private boolean needClearCache = false;
private Map<String, Texture> oldTexCache = new HashMap<String, Texture>(); private Map<String, Texture> oldTexCache = new HashMap<String, Texture>();
private Map<String, Texture> texCache = new HashMap<String, Texture>(); private Map<String, Texture> texCache = new HashMap<String, Texture>();
private float anisotrophy = 0; private float anisotrophy = 0;
@ -69,10 +68,9 @@ public class RealisticRenderer extends RocketRenderer {
} }
@Override @Override
public void updateFigure() { public void updateFigure(GLAutoDrawable drawable) {
super.updateFigure(); super.updateFigure(drawable);
clearCaches(drawable.getGL().getGL2());
needClearCache = true;
} }
@Override @Override
@ -95,12 +93,6 @@ public class RealisticRenderer extends RocketRenderer {
@Override @Override
public void renderComponent(GL2 gl, RocketComponent c, float alpha) { public void renderComponent(GL2 gl, RocketComponent c, float alpha) {
if (needClearCache) {
clearCaches(gl);
needClearCache = false;
}
final Appearance a = getAppearance(c); final Appearance a = getAppearance(c);
final Decal t = a.getTexture(); final Decal t = a.getTexture();
final Texture tex = getTexture(t); final Texture tex = getTexture(t);

View File

@ -518,8 +518,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
public void updateFigure() { public void updateFigure() {
log.debug("3D Figure Updated"); log.debug("3D Figure Updated");
cachedBounds = null; cachedBounds = null;
rr.updateFigure(); canvas.invoke(true, new GLRunnable() {
internalRepaint(); @Override
public boolean run(GLAutoDrawable drawable) {
rr.updateFigure(drawable);
return false;
}
});
} }
private void internalRepaint() { private void internalRepaint() {

View File

@ -38,8 +38,8 @@ public abstract class RocketRenderer {
public void dispose(GLAutoDrawable drawable) { public void dispose(GLAutoDrawable drawable) {
} }
public void updateFigure() { public void updateFigure(GLAutoDrawable drawable) {
cr.updateFigure(); cr.updateFigure(drawable);
} }
public abstract void renderComponent(GL2 gl, RocketComponent c, float alpha); public abstract void renderComponent(GL2 gl, RocketComponent c, float alpha);