public void init(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); glu = new GLU(); /* * jogl specific addition for tessellation */ tessellCallBack tessCallback = new tessellCallBack(gl, glu); // double rect[][] = new double[][] { // [4][3] in C; reverse here {50.0, 50.0, 0.0}, {200.0, 50.0, 0.0}, {200.0, 200.0, 0.0}, {50.0, 200.0, 0.0} }; double tri[][] = new double[][] { // [3][3] {75.0, 75.0, 0.0}, {125.0, 175.0, 0.0}, {175.0, 75.0, 0.0} }; double star[][] = new double[][] { // [5][6]; 6x5 in java {250.0, 50.0, 0.0, 1.0, 0.0, 1.0}, {325.0, 200.0, 0.0, 1.0, 1.0, 0.0}, {400.0, 50.0, 0.0, 0.0, 1.0, 1.0}, {250.0, 150.0, 0.0, 1.0, 0.0, 0.0}, {400.0, 150.0, 0.0, 0.0, 1.0, 0.0} }; gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); startList = gl.glGenLists(2); GLUtessellator tobj = glu.gluNewTess(); glu.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, tessCallback); // glVertex3dv); glu.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, tessCallback); // beginCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_END, tessCallback); // endCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_ERROR, tessCallback); // errorCallback); /* rectangle with triangular hole inside */ gl.glNewList(startList, GL2.GL_COMPILE); gl.glShadeModel(GL2.GL_FLAT); glu.gluTessBeginPolygon(tobj, null); glu.gluTessBeginContour(tobj); glu.gluTessVertex(tobj, rect[0], 0, rect[0]); glu.gluTessVertex(tobj, rect[1], 0, rect[1]); glu.gluTessVertex(tobj, rect[2], 0, rect[2]); glu.gluTessVertex(tobj, rect[3], 0, rect[3]); glu.gluTessEndContour(tobj); glu.gluTessBeginContour(tobj); glu.gluTessVertex(tobj, tri[0], 0, tri[0]); glu.gluTessVertex(tobj, tri[1], 0, tri[1]); glu.gluTessVertex(tobj, tri[2], 0, tri[2]); glu.gluTessEndContour(tobj); glu.gluTessEndPolygon(tobj); gl.glEndList(); glu.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, tessCallback); // vertexCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, tessCallback); // beginCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_END, tessCallback); // endCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_ERROR, tessCallback); // errorCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_COMBINE, tessCallback); // combineCallback); /* smooth shaded, self-intersecting star */ gl.glNewList(startList + 1, GL2.GL_COMPILE); gl.glShadeModel(GL2.GL_SMOOTH); glu.gluTessProperty( tobj, // GLU.GLU_TESS_WINDING_RULE, // GLU.GLU_TESS_WINDING_POSITIVE); glu.gluTessBeginPolygon(tobj, null); glu.gluTessBeginContour(tobj); glu.gluTessVertex(tobj, star[0], 0, star[0]); glu.gluTessVertex(tobj, star[1], 0, star[1]); glu.gluTessVertex(tobj, star[2], 0, star[2]); glu.gluTessVertex(tobj, star[3], 0, star[3]); glu.gluTessVertex(tobj, star[4], 0, star[4]); glu.gluTessEndContour(tobj); glu.gluTessEndPolygon(tobj); gl.glEndList(); glu.gluDeleteTess(tobj); }
private TessOutput tesselateString(String s) { GlyphVector gv = _font.createGlyphVector(_frc, s); Shape shape = gv.getOutline(); // AffineTransform at = new AffineTransform(); at.scale(1, -1); PathIterator pIt = shape.getPathIterator(at, _font.getSize() / 200.0); // Create a GLU tesselator GLUtessellator tess = GLU.gluNewTess(); CharTesselator tessAdapt = new CharTesselator(); GLU.gluTessCallback(tess, GLU.GLU_TESS_VERTEX, tessAdapt); GLU.gluTessCallback(tess, GLU.GLU_TESS_BEGIN, tessAdapt); GLU.gluTessCallback(tess, GLU.GLU_TESS_END, tessAdapt); GLU.gluTessCallback(tess, GLU.GLU_TESS_COMBINE, tessAdapt); GLU.gluTessCallback(tess, GLU.GLU_TESS_ERROR, tessAdapt); int winding = pIt.getWindingRule(); if (winding == PathIterator.WIND_EVEN_ODD) GLU.gluTessProperty(tess, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_ODD); else if (winding == PathIterator.WIND_NON_ZERO) GLU.gluTessProperty(tess, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_NONZERO); else assert (false); // PathIterator should only return these two winding rules GLU.gluBeginPolygon(tess); GLU.gluTessNormal(tess, 0, 0, 1); double[] first = null; double[] v; while (!pIt.isDone()) { v = new double[3]; int type = pIt.currentSegment(v); v[2] = 0.0; if (type == PathIterator.SEG_MOVETO) { first = v; GLU.gluNextContour(tess, GLU.GLU_UNKNOWN); GLU.gluTessVertex(tess, v, 0, v); } else if (type == PathIterator.SEG_LINETO) { GLU.gluTessVertex(tess, v, 0, v); } else if (type == PathIterator.SEG_CLOSE) { assert (first != null); // If this is true, there is an error in the AWT path iterator GLU.gluTessVertex(tess, first, 0, first); first = null; } else { assert (false); // The path itertor should not return other path types here } pIt.next(); } GLU.gluEndPolygon(tess); int numVerts = tessAdapt.getVerts().size(); double[] verts = new double[numVerts]; int count = 0; for (double d : tessAdapt.getVerts()) { verts[count++] = d; } TessOutput ret = new TessOutput(); ret.verts = verts; ret.bounds = gv.getVisualBounds(); ret.advances = new double[s.length()]; for (int i = 0; i < s.length(); ++i) { ret.advances[i] = gv.getGlyphMetrics(i).getAdvance(); } return ret; }