pgraphicsopengl.java
来自「This is processing for java examples.」· Java 代码 · 共 2,167 行 · 第 1/5 页
JAVA
2,167 行
//public void imageMode(int mode) //public void image(PImage image, float x, float y) //public void image(PImage image, float x, float y, float c, float d) //public void image(PImage image, // float a, float b, float c, float d, // int u1, int v1, int u2, int v2) //protected void imageImpl(PImage image, // float x1, float y1, float x2, float y2, // int u1, int v1, int u2, int v2) ////////////////////////////////////////////////////////////// // SHAPE //public void shapeMode(int mode) //public void shape(PShape shape) //public void shape(PShape shape, float x, float y) //public void shape(PShape shape, float x, float y, float c, float d) ////////////////////////////////////////////////////////////// // TEXT SETTINGS //public void textAlign(int align) //public void textAlign(int alignX, int alignY) public float textAscent() { Font font = textFont.getFont(); if ((textMode != SHAPE) || (font == null)) { return super.textAscent(); } FontMetrics metrics = parent.getFontMetrics(font); return metrics.getAscent(); } public float textDescent() { Font font = textFont.getFont(); if ((textMode != SHAPE) || (font == null)) { return super.textDescent(); } FontMetrics metrics = parent.getFontMetrics(font); return metrics.getDescent(); } public void textFont(PFont which) { super.textFont(which); if (textMode == SHAPE) { if (textFont.findFont() == null) { showWarning("Cannot use " + which.name + " as with textMode(SHAPE) " + "because its native equivalent cannot be found."); } } } //public void textFont(PFont which, float size) //public void textLeading(float leading)// public void textMode(int mode) {// if (mode == SHAPE) {// textMode = SHAPE;//// } else {// // if not SHAPE mode, then pass off to the PGraphics.textMode()// // which is built for error handling (but objects to SHAPE).// super.textMode(mode);// }// } protected boolean textModeCheck(int mode) { return (textMode == MODEL) || (textMode == SCREEN) || (textMode == SHAPE); } /** * Same as parent, but override for native version of the font. * <p/> * Also gets called by textFont, so the metrics * will get recorded properly. */// public void textSize(float size) { // can't cancel on textMode(SHAPE) because textMode() must happen // after textFont() and textFont() calls textSize() //if ((textMode != SHAPE) || (textFontNative == null)) { // call this anyway to set the base variables for cases // where textMode(SHAPE) will not be used// super.textSize(size); /* // derive the font just in case the user is gonna call // textMode(SHAPE) afterwards if (textFontNative != null) { textFontNative = textFontNative.deriveFont(size); Graphics2D graphics = (Graphics2D) parent.getGraphics(); graphics.setFont(textFontNative); // get the metrics info textFontNativeMetrics = graphics.getFontMetrics(textFontNative); } */// } //public float textWidth(char c) //public float textWidth(String str) protected float textWidthImpl(char buffer[], int start, int stop) { Font font = textFont.getFont(); if ((textMode != SHAPE) || (font == null)) { return super.textWidthImpl(buffer, start, stop); } /* // maybe should use one of the newer/fancier functions for this? int length = stop - start; return textFontNativeMetrics.charsWidth(buffer, start, length); */ Graphics2D graphics = (Graphics2D) parent.getGraphics(); // otherwise smaller sizes will be totally crapped up // seems to need to be before the getFRC, but after the canvas.getGraphics // (placing this inside textSize(), even though it was called, wasn't working) graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); FontRenderContext frc = graphics.getFontRenderContext(); GlyphVector gv; /* if (start == 0 && stop == buffer.length) { gv = textFontNative.createGlyphVector(frc, buffer); } else { char[] fellas = PApplet.subset(buffer, start, length); gv = textFontNative.createGlyphVector(frc, fellas); } */ gv = font.createGlyphVector(frc, buffer); float sum = 0; for (int i = start; i < stop; i++) { GlyphMetrics gm = gv.getGlyphMetrics(i); sum += gm.getAdvance(); } return sum; } ////////////////////////////////////////////////////////////// // TEXT // None of the variations of text() are overridden from PGraphics. ////////////////////////////////////////////////////////////// // TEXT IMPL //protected void textLineAlignImpl(char buffer[], int start, int stop, // float x, float y) //protected void textLineImpl(char buffer[], int start, int stop, // float x, float y) /** * Override to handle rendering characters with textMode(SHAPE). */ protected void textCharImpl(char ch, float x, float y) { if (textMode == SHAPE) { if (textFont.getFont() == null) { PGraphics.showWarning("textMode(SHAPE) is disabled because the font " + "\"" + textFont.name + "\" is not available."); } else { textCharShapeImpl(ch, x, y); } } else { super.textCharImpl(ch, x, y); } } /** * This uses the tesselation functions from GLU to handle triangulation * to convert the character into a series of shapes. * <p/> * <EM>No attempt has been made to optimize this code</EM> * <p/> * TODO: Should instead override textPlacedImpl() because createGlyphVector * takes a char array. Or better yet, cache the font on a per-char basis, * so that it's not being re-tessellated each time, could make it into * a display list which would be nice and speedy. * <p/> * Also a problem where some fonts seem to be a bit slight, as if the * control points aren't being mapped quite correctly. Probably doing * something dumb that the control points don't map to P5's control * points. Perhaps it's returning b-spline data from the TrueType font? * Though it seems like that would make a lot of garbage rather than * just a little flattening. * <p/> * There also seems to be a bug that is causing a line (but not a filled * triangle) back to the origin on some letters (i.e. a capital L when * tested with Akzidenz Grotesk Light). But this won't be visible * with the stroke shut off, so tabling that bug for now. */ protected void textCharShapeImpl(char ch, float x, float y) { // save the current stroke because it needs to be disabled // while the text is being drawn boolean strokeSaved = stroke; stroke = false; // six element array received from the Java2D path iterator float textPoints[] = new float[6]; // array passed to createGylphVector char textArray[] = new char[] { ch }; Graphics2D graphics = (Graphics2D) parent.getGraphics(); FontRenderContext frc = graphics.getFontRenderContext(); Font font = textFont.getFont(); GlyphVector gv = font.createGlyphVector(frc, textArray); Shape shp = gv.getOutline(); //PathIterator iter = shp.getPathIterator(null, 0.05); PathIterator iter = shp.getPathIterator(null); glu.gluTessBeginPolygon(tobj, null); // second param to gluTessVertex is for a user defined object that contains // additional info about this point, but that's not needed for anything float lastX = 0; float lastY = 0; // unfortunately the tesselator won't work properly unless a // new array of doubles is allocated for each point. that bites ass, // but also just reaffirms that in order to make things fast, // display lists will be the way to go. double vertex[]; final boolean DEBUG_OPCODES = false; //true; while (!iter.isDone()) { int type = iter.currentSegment(textPoints); switch (type) { case PathIterator.SEG_MOVETO: // 1 point (2 vars) in textPoints case PathIterator.SEG_LINETO: // 1 point if (type == PathIterator.SEG_MOVETO) { if (DEBUG_OPCODES) { System.out.println("moveto\t" + textPoints[0] + "\t" + textPoints[1]); } glu.gluTessBeginContour(tobj); } else { if (DEBUG_OPCODES) { System.out.println("lineto\t" + textPoints[0] + "\t" + textPoints[1]); } } vertex = new double[] { x + textPoints[0], y + textPoints[1], 0 }; glu.gluTessVertex(tobj, vertex, 0, vertex); lastX = textPoints[0]; lastY = textPoints[1]; break; case PathIterator.SEG_QUADTO: // 2 points if (DEBUG_OPCODES) { System.out.println("quadto\t" + textPoints[0] + "\t" + textPoints[1] + "\t" + textPoints[2] + "\t" + textPoints[3]); } for (int i = 1; i < bezierDetail; i++) { float t = (float)i / (float)bezierDetail; vertex = new double[] { x + bezierPoint(lastX, lastX + (float) ((textPoints[0] - lastX) * 2/3.0), textPoints[2] + (float) ((textPoints[0] - textPoints[2]) * 2/3.0), textPoints[2], t), y + bezierPoint(lastY, lastY + (float) ((textPoints[1] - lastY) * 2/3.0), textPoints[3] + (float) ((textPoints[1] - textPoints[3]) * 2/3.0), textPoints[3], t), 0.0f }; glu.gluTessVertex(tobj, vertex, 0, vertex); } lastX = textPoints[2]; lastY = textPoints[3]; break; case PathIterator.SEG_CUBICTO: // 3 points if (DEBUG_OPCODES) { System.out.println("cubicto\t" + textPoints[0] + "\t" + textPoints[1] + "\t" + textPoints[2] + "\t" + textPoints[3] + "\t" + textPoints[4] + "\t" + textPoints[5]); } for (int i = 1; i < bezierDetail; i++) { float t = (float)i / (float)bezierDetail; vertex = new double[] { x + bezierPoint(lastX, textPoints[0], textPoints[2], textPoints[4], t), y + bezierPoint(lastY, textPoints[1], textPoints[3], textPoints[5], t), 0 }; glu.gluTessVertex(tobj, vertex, 0, vertex); } lastX = textPoints[4]; lastY = textPoints[5]; break; case PathIterator.SEG_CLOSE: if (DEBUG_OPCODES) { System.out.println("close"); System.out.println(); } glu.gluTessEndContour(tobj); break; } iter.next(); } glu.gluTessEndPolygon(tobj); // re-enable stroke if it was in use before stroke = strokeSaved; } /** * There must be a better way to do this, but I'm having a brain fart * with all the inner class crap. Fix it later once this stuff is debugged. * <p/> * The method "void vertex(float $1, float $2, float $3);" contained in * the enclosing type "processing.core.PGraphics3" is a perfect match for * this method call. However, it is not visible in this nested class because * a method with the same name in an intervening class is hiding it. */ /* public void vertexRedirect(float x, float y, float z) { vertex(x, y, z); } */ public class TessCallback extends GLUtessellatorCallbackAdapter { public void begin(int type) { switch (type) { case GL.GL_TRIANGLE_FAN: beginShape(TRIANGLE_FAN); break; case GL.GL_TRIANGLE_STRIP: beginShape(TRIANGLE_STRIP); break; case GL.GL_TRIANGLES: beginShape(TRIANGLES); break; } } public void end() { //gl.glEnd(); endShape(); } public void edge(boolean e) { PGraphicsOpenGL.this.edge(e); } public void vertex(Object data) { if (data instanceof double[]) { double[] d = (double[]) data; if (d.length != 3) { throw new RuntimeException("TessCallback vertex() data " + "isn't length 3"); } //System.out.println("tess callback vertex " + // d[0] + " " + d[1] + " " + d[2]); //vertexRedirect((float) d[0], (float) d[1], (float) d[2]); PGraphicsOpenGL.this.vertex((float) d[0], (float) d[1], (float) d[2]); /* if (d.length == 6) { double[] d2 = {d[0], d[1], d[2]}; gl.glVertex3dv(d2); d2 = new double[]{d[3], d[4], d[5]}; gl.glColor3dv(d2); } else if (d.length == 3) { gl.glVertex3dv(d); } */ } else { throw new RuntimeException("TessCallback vertex() data not understood"); } } public void error(int errnum) { String estring = glu.gluErrorString(errnum); PGraphics.showWarning("Tessellation Error: " + estring); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?