diff options
author | eteq <[email protected]> | 2007-02-07 11:10:38 +0000 |
---|---|---|
committer | eteq <[email protected]> | 2007-02-07 11:10:38 +0000 |
commit | 208b84ae11288b4edd190364528289240303cb5d (patch) | |
tree | 1100d48bdbdc71d3d41e08641590a6b0c796adef /src/net/java | |
parent | f4fed24a1034b90201765e7e4c4b1cf570d210f8 (diff) |
Re-vamped internals of FontDrawer class, improved FontDrawerDemo, and changed FontDrawer to use an enum for specifying normal calculations
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/joglutils/trunk@43 83d24430-9974-4f80-8418-2cc3294053b9
Diffstat (limited to 'src/net/java')
-rw-r--r-- | src/net/java/joglutils/jogltext/FontDrawer.java | 220 |
1 files changed, 170 insertions, 50 deletions
diff --git a/src/net/java/joglutils/jogltext/FontDrawer.java b/src/net/java/joglutils/jogltext/FontDrawer.java index d50e1a8..1bf148b 100644 --- a/src/net/java/joglutils/jogltext/FontDrawer.java +++ b/src/net/java/joglutils/jogltext/FontDrawer.java @@ -1,21 +1,21 @@ /*
* Copyright (c) 2006 Erik Tollerud ([email protected]) All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* The names of Erik Tollerud, Davide Raccagni, Sun Microsystems, Inc. or the names of
* contributors may not be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -23,12 +23,12 @@ * SUN MICROSYSTEMS, INC. ("SUN"), AND SUN'S LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL ERIK
- * TOLLERUD, SUN, OR SUN'S LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
+ * TOLLERUD, SUN, OR SUN'S LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
* OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF ERIK
* TOLLERUD OR SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
@@ -52,27 +52,45 @@ import javax.media.opengl.glu.*; */
public class FontDrawer {
+ public enum NormalMode {NONE, FLAT, AVERAGED};
+
private Font font;
private float depth;
private boolean edgeOnly;
- private boolean flatNorm;
+ private NormalMode normalMode;
+ /**
+ * Intstantiates a new FontDrawer initially rendering in the specified font.
+ * @param font the initial font for this FontDrawer
+ */
public FontDrawer(Font font) {
this.font = font;
depth = 0;
edgeOnly = false;
- flatNorm = true;
+ normalMode = NormalMode.FLAT;
}
+ /**
+ * Specifies which font to render with this FontDrawer
+ * @param font a font to use for rendering
+ */
public void setFont(Font font) {
this.font = font;
}
+ /**
+ * Retrieves the Font currently associated with this FontDrawer
+ * @return the Font in which this object renders strings
+ */
public Font getFont() {
return this.font;
}
+ /**
+ * Determines how long the sides of the rendered text is. In the special case of 0, the rendering is 2D.
+ * @param depth specifies the z-size of the rendered 3D text. Negative numbers will be set to 0.
+ */
public void setDepth(float depth) {
if (depth <= 0)
this.depth = 0;
@@ -80,47 +98,126 @@ public class FontDrawer { this.depth = depth;
}
+ /**
+ * Retrieves the z-depth used for this FontDrawer's text rendering.
+ * @return the z-depth of the rendered 3D text.
+ */
public float getDepth() {
return this.depth;
}
+ /**
+ * Sets if the text should be rendered as filled polygons or wireframe.
+ * @param fill if true, uses filled polygons, if false, renderings are wireframe.
+ */
public void setFill(boolean fill) {
this.edgeOnly = !fill;
}
+ /**
+ * Determines if the text is being rendered as filled polygons or wireframes.
+ * @return if true, uses filled polygons, if false, renderings are wireframe.
+ */
public boolean isFill() {
return !this.edgeOnly;
}
- public void setFlatNormals( boolean flat ) {
- this.flatNorm = flat;
+ /**
+ * Sets technique for rendering Normals. Available options:
+ * None: Performs no calls to glNormal* - best performance
+ * Flat: Computes the normal as pointing straight away from the text face.
+ * Averaged: Determines side edge normals as the average direction of the two sides (smoother shading). Faces are still flat.
+ *
+ * @param mode the mode to render in. Default is flat.
+ */
+ public void setNormal( NormalMode mode ) {
+ this.normalMode = mode;
}
- public boolean isFlatNormals() {
- return this.flatNorm;
+ /**
+ * Determines which normal-calculation technique is being used.
+ * @see setNormal
+ * @return the normal technique for this FontDrawer.
+ */
+ public NormalMode getNormal() {
+ return this.normalMode;
}
+ /**
+ * Renders a string into the specified GL object, starting at the (0,0,0) point in OpenGL coordinates.
+ * Note that this creates a new GLU instance everytime it is called, which will negatively impact performance.
+ *
+ * @param str the string to render.
+ * @param gl the OpenGL context in which to render the text.
+ */
+ public void drawString(String str, GL gl) {
+ drawString(str,new GLU(),gl);
+ }
+
+ /**
+ * Renders a string into the specified GL object, starting at the (0,0,0) point in OpenGL coordinates.
+ *
+ * @param str the string to render.
+ * @param glu a GLU instance to use for the text rendering (provided to prevent continuous re-instantiation of a GLU object)
+ * @param gl the OpenGL context in which to render the text.
+ */
public void drawString(String str, GLU glu, GL gl) {
GlyphVector gv = font.createGlyphVector(
new FontRenderContext(new AffineTransform(), true, true),
new StringCharacterIterator(str));
GeneralPath gp = (GeneralPath)gv.getOutline();
PathIterator pi = gp.getPathIterator(AffineTransform.getScaleInstance(1.0, -1.0), 1.0f);
- gl.glNormal3i(0,0,-1);
+
+ if (this.normalMode != NormalMode.NONE)
+ gl.glNormal3f(0,0,-1.0f);
tesselateFace(glu, gl, pi, pi.getWindingRule(), this.edgeOnly);
if (this.depth != 0.0) {
pi = gp.getPathIterator(AffineTransform.getScaleInstance(1.0, -1.0), 1.0f);
- gl.glNormal3i(0,0,1);
+ if (this.normalMode != NormalMode.NONE)
+ gl.glNormal3f(0,0,1.0f);
tesselateFace(glu, gl, pi, pi.getWindingRule(), this.edgeOnly, this.depth);
pi = gp.getPathIterator(AffineTransform.getScaleInstance(1.0, -1.0), 1.0f);
- if (this.flatNorm)
- drawSidesFlatNorm(gl,pi,this.edgeOnly,this.depth);
- else
- drawSidesAvgNorm(gl,pi,this.edgeOnly,this.depth);
+ switch (this.normalMode) {
+ //TODO: add diagonal corner/VBO technique
+ case NONE:
+ drawSidesNoNorm(gl,pi,this.edgeOnly,this.depth);
+ break;
+ case FLAT:
+ drawSidesFlatNorm(gl,pi,this.edgeOnly,this.depth);
+ break;
+ case AVERAGED:
+ drawSidesAvgNorm(gl,pi,this.edgeOnly,this.depth);
+ break;
+ }
}
+
}
+ /**
+ * Renders a string into the specified GL object, starting at the (xOff,yOff,zOff) point in OpenGL coordinates.
+ * Note that this creates a new GLU instance everytime it is called, which will negatively impact performance.
+ *
+ * @param xOff the distance to translate the text in the x-direction
+ * @param yOff the distance to translate the text in the y-direction
+ * @param zOff the distance to translate the text in the z-direction
+ * @param str the string to render.
+ * @param gl the OpenGL context in which to render the text.
+ */
+ public void drawString(String str, GL gl, float xOff, float yOff, float zOff) {
+ drawString(str,new GLU(),gl,xOff,yOff,zOff);
+ }
+
+ /**
+ * Renders a string into the specified GL object, starting at the (xOff,yOff,zOff) point in OpenGL coordinates.
+ *
+ * @param xOff the distance to translate the text in the x-direction
+ * @param yOff the distance to translate the text in the y-direction
+ * @param zOff the distance to translate the text in the z-direction
+ * @param str the string to render.
+ * @param glu a GLU instance to use for the text rendering (provided to prevent continuous re-instantiation of a GLU object)
+ * @param gl the OpenGL context in which to render the text.
+ */
public void drawString(String str, GLU glu, GL gl, float xOff, float yOff, float zOff) {
gl.glPushAttrib(GL.GL_TRANSFORM_BIT);
gl.glMatrixMode(GL.GL_MODELVIEW);
@@ -185,9 +282,51 @@ public class FontDrawer { glu.gluDeleteTess(tess);
}
+ private void drawSidesNoNorm(GL gl, PathIterator pi, boolean justBoundary,float tessZ) {
+ //TODO: texture coords
+
+ if (justBoundary)
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK,GL.GL_LINE);
+ else
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK,GL.GL_FILL);
+
+ for(float[] coords = new float[6];!pi.isDone();pi.next()) {
+ float[] currRender = new float[3];
+ switch(pi.currentSegment(coords)) {
+ case PathIterator.SEG_MOVETO:
+ gl.glBegin(GL.GL_QUAD_STRIP);
+ currRender[0] = coords[0];
+ currRender[1] = coords[1];
+ currRender[2] = 0;
+ gl.glVertex3fv(currRender,0);
+ currRender[2] = tessZ;
+ gl.glVertex3fv(currRender,0);
+ break;
+ case PathIterator.SEG_LINETO:
+ currRender[0] = coords[0];
+ currRender[1] = coords[1];
+ currRender[2] = 0;
+ gl.glVertex3fv(currRender,0);
+ currRender[2] = tessZ;
+ gl.glVertex3fv(currRender,0);
+ break;
+ case PathIterator.SEG_CLOSE:
+ currRender[0] = coords[0];
+ currRender[1] = coords[1];
+ currRender[2] = 0;
+ gl.glVertex3fv(currRender,0);
+ currRender[2] = tessZ;
+ gl.glVertex3fv(currRender,0);
+ gl.glEnd();
+ break;
+ default:
+ throw new JogltextException("PathIterator segment not SEG_MOVETO, SEG_LINETO, SEG_CLOSE; Inappropriate font.");
+ }
+ }
+ }
+
private void drawSidesFlatNorm(GL gl, PathIterator pi, boolean justBoundary,float tessZ) {
- //TODO: work out texture coords
- //TODO:work out double vs. float
+ //TODO: texture coords
if (justBoundary)
gl.glPolygonMode(GL.GL_FRONT_AND_BACK,GL.GL_LINE);
@@ -234,15 +373,16 @@ public class FontDrawer { gl.glEnd();
break;
default:
- throw new JogltextException("PathIterator segment not SEG_MOVETO, SEG_LINETO, SEG_CLOSE");
+ throw new JogltextException("PathIterator segment not SEG_MOVETO, SEG_LINETO, SEG_CLOSE; Inappropriate font.");
}
}
}
private void drawSidesAvgNorm(GL gl, PathIterator pi, boolean justBoundary,float tessZ) {
- //TODO: work out texture coords
- //TODO: improve performance
+ //TODO: improve performance with some form of caching?
+ //TODO: texture coords
+ //TODO: check last coord - might not quite be correct?
if (justBoundary)
gl.glPolygonMode(GL.GL_FRONT_AND_BACK,GL.GL_LINE);
@@ -253,8 +393,6 @@ public class FontDrawer { float[] firstCoord = null;
float[] secondCoord = null;
float[] thirdCoord = null;
- float[] secondNorm = null;
- float[] thirdNorm = null;
float[] twoBackCoord = null;
float[] oneBackCoord = null;
for(float[] coords = new float[6];!pi.isDone();pi.next()) {
@@ -279,19 +417,9 @@ public class FontDrawer { thirdCoord = new float[3];
thirdCoord[0] = coords[0];
thirdCoord[1] = coords[1];
+
}
- if (secondNorm == null) {
- secondNorm = new float[3];
- secondNorm[0] = avgdeltay;
- secondNorm[1] = -avgdeltax;
- secondNorm[2] = 0;
- } else if (thirdNorm == null) {
- thirdNorm = new float[3];
- thirdNorm[0] = avgdeltay;
- thirdNorm[1] = -avgdeltax;
- thirdNorm[2] = 0;
- }
- gl.glNormal3f(avgdeltay,-avgdeltax,0);
+ gl.glNormal3f(-avgdeltay,avgdeltax,0);
oneBackCoord[2] = 0.0f;
gl.glVertex3fv(oneBackCoord,0);
oneBackCoord[2] = tessZ;
@@ -307,7 +435,7 @@ public class FontDrawer { case PathIterator.SEG_CLOSE:
float avgdeltax = oneBackCoord[0] - twoBackCoord[0] + firstCoord[0] - oneBackCoord[0];
float avgdeltay = oneBackCoord[1] - twoBackCoord[1] + firstCoord[1] - oneBackCoord[1];
- gl.glNormal3f(avgdeltay,-avgdeltax,0);
+ gl.glNormal3f(-avgdeltay,avgdeltax,0);
oneBackCoord[2] = 0.0f;
gl.glVertex3fv(oneBackCoord,0);
oneBackCoord[2] = tessZ;
@@ -315,7 +443,7 @@ public class FontDrawer { avgdeltax = firstCoord[0] - oneBackCoord[0] + secondCoord[0] - firstCoord[0];
avgdeltay = firstCoord[1] - oneBackCoord[1] + secondCoord[1] - firstCoord[1];
- gl.glNormal3f(avgdeltay,-avgdeltax,0);
+ gl.glNormal3f(-avgdeltay,avgdeltax,0);
firstCoord[2] = 0.0f;
gl.glVertex3fv(firstCoord,0);
firstCoord[2] = tessZ;
@@ -323,29 +451,21 @@ public class FontDrawer { avgdeltax = secondCoord[0] - firstCoord[0] + thirdCoord[0] - secondCoord[0];
avgdeltay = secondCoord[1] - firstCoord[1] + thirdCoord[1] - secondCoord[1];
- gl.glNormal3f(avgdeltay,-avgdeltax,0);
- //gl.glNormal3fv(secondNorm,0);
+ gl.glNormal3f(-avgdeltay,avgdeltax,0);
secondCoord[2] = 0.0f;
gl.glVertex3fv(secondCoord,0);
secondCoord[2] = tessZ;
gl.glVertex3fv(secondCoord,0);
- /*gl.glNormal3fv(thirdNorm,0);
- thirdCoord[2] = 0.0f;
- gl.glVertex3fv(thirdCoord,0);
- thirdCoord[2] = tessZ;
- gl.glVertex3fv(thirdCoord,0);*/
gl.glEnd();
firstCoord = null;
secondCoord = null;
thirdCoord = null;
- secondNorm = null;
- thirdNorm = null;
twoBackCoord = null;
oneBackCoord = null;
break;
default:
- throw new JogltextException("PathIterator segment not SEG_MOVETO, SEG_LINETO, SEG_CLOSE");
+ throw new JogltextException("PathIterator segment not SEG_MOVETO, SEG_LINETO, SEG_CLOSEE; Inappropriate font.");
}
}
}
|