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 + -
显示快捷键?