From 626bc8f70cc080623c0e1ea97ee44a1b956a863e Mon Sep 17 00:00:00 2001 From: codeanticode Date: Tue, 15 Oct 2013 23:41:42 -0400 Subject: [PATCH] removed first,last vertex and count from InGeometry, implementing vertex codes --- .../processing/opengl/PGraphicsOpenGL.java | 1114 +++++++++++------ core/src/processing/opengl/PShader.java | 17 +- core/src/processing/opengl/PShapeOpenGL.java | 274 +++- 3 files changed, 978 insertions(+), 427 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 3cd19c3cd..3b0cdace3 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -531,7 +531,7 @@ public class PGraphicsOpenGL extends PGraphics { final static protected float POINT_ACCURACY_FACTOR = 10.0f; /** Used in quad point tessellation. */ - final protected float[][] QUAD_POINT_SIGNS = + final static protected float[][] QUAD_POINT_SIGNS = { {-1, +1}, {-1, -1}, {+1, -1}, {+1, +1} }; /** To get data from OpenGL. */ @@ -559,8 +559,8 @@ public class PGraphicsOpenGL extends PGraphics { viewport = PGL.allocateIntBuffer(4); - inGeo = newInGeometry(IMMEDIATE); - tessGeo = newTessGeometry(IMMEDIATE); + inGeo = newInGeometry(this, IMMEDIATE); + tessGeo = newTessGeometry(this, IMMEDIATE); texCache = newTexCache(); initialized = false; @@ -2067,7 +2067,7 @@ public class PGraphicsOpenGL extends PGraphics { @Override public void beginShape(int kind) { shape = kind; - curveVertexCount = 0; +// curveVertexCount = 0; inGeo.clear(); breakShape = true; @@ -2196,17 +2196,16 @@ public class PGraphicsOpenGL extends PGraphics { u, v, scolor, sweight, ambientColor, specularColor, emissiveColor, shininess, - vertexCode()); + VERTEX, vertexBreak()); } - protected int vertexCode() { - int code = VERTEX; + protected boolean vertexBreak() { if (breakShape) { - code = BREAK; breakShape = false; + return true; } - return code; + return false; } @@ -2249,12 +2248,13 @@ public class PGraphicsOpenGL extends PGraphics { tessellator.setInGeometry(inGeo); tessellator.setTessGeometry(tessGeo); tessellator.setFill(fill || textureImage != null); + tessellator.setTexCache(texCache, textureImage0, textureImage); tessellator.setStroke(stroke); tessellator.setStrokeColor(strokeColor); tessellator.setStrokeWeight(strokeWeight); tessellator.setStrokeCap(strokeCap); tessellator.setStrokeJoin(strokeJoin); - tessellator.setTexCache(texCache, textureImage0, textureImage); + tessellator.setRenderer(pgCurrent); tessellator.setTransform(modelview); tessellator.set3D(is3D()); @@ -2279,8 +2279,6 @@ public class PGraphicsOpenGL extends PGraphics { if (normalMode == NORMAL_MODE_AUTO) inGeo.calcTriangleStripNormals(); tessellator.tessellateTriangleStrip(); } else if (shape == QUAD || shape == QUADS) { - - if (stroke && defaultEdges) inGeo.addQuadsEdges(); if (normalMode == NORMAL_MODE_AUTO) inGeo.calcQuadsNormals(); tessellator.tessellateQuads(); @@ -2793,9 +2791,7 @@ public class PGraphicsOpenGL extends PGraphics { inGeo.setNormal(normalX, normalY, normalZ); inGeo.addBezierVertex(x2, y2, z2, x3, y3, z3, - x4, y4, z4, - fill, stroke, bezierDetail, vertexCode(), shape); - + x4, y4, z4, vertexBreak()); } @@ -2821,8 +2817,7 @@ public class PGraphicsOpenGL extends PGraphics { ambientColor, specularColor, emissiveColor, shininess); inGeo.setNormal(normalX, normalY, normalZ); inGeo.addQuadraticVertex(cx, cy, cz, - x3, y3, z3, - fill, stroke, bezierDetail, vertexCode(), shape); + x3, y3, z3, vertexBreak()); } @@ -2847,8 +2842,7 @@ public class PGraphicsOpenGL extends PGraphics { inGeo.setMaterial(fillColor, strokeColor, strokeWeight, ambientColor, specularColor, emissiveColor, shininess); inGeo.setNormal(normalX, normalY, normalZ); - inGeo.addCurveVertex(x, y, z, - fill, stroke, curveDetail, vertexCode(), shape); + inGeo.addCurveVertex(x, y, z, vertexBreak()); } @@ -2939,7 +2933,21 @@ public class PGraphicsOpenGL extends PGraphics { x2, y2, 0, x3, y3, 0, x4, y4, 0, - fill, stroke); + stroke); + endShape(); + } + + + @Override + protected void rectImpl(float x1, float y1, float x2, float y2, + float tl, float tr, float br, float bl) { + beginShape(POLYGON); + defaultEdges = false; + normalMode = NORMAL_MODE_SHAPE; + inGeo.setMaterial(fillColor, strokeColor, strokeWeight, + ambientColor, specularColor, emissiveColor, shininess); + inGeo.setNormal(normalX, normalY, normalZ); + inGeo.addRect(x1, y1, x2, y2, tl, tr, br, bl, stroke); endShape(); } @@ -2948,8 +2956,6 @@ public class PGraphicsOpenGL extends PGraphics { // ELLIPSE - // public void ellipseMode(int mode) - @Override public void ellipseImpl(float a, float b, float c, float d) { @@ -2964,9 +2970,6 @@ public class PGraphicsOpenGL extends PGraphics { } - // public void ellipse(float a, float b, float c, float d) - - @Override protected void arcImpl(float x, float y, float w, float h, float start, float stop, int mode) { @@ -3008,6 +3011,10 @@ public class PGraphicsOpenGL extends PGraphics { @Override public void sphere(float r) { + if ((sphereDetailU < 3) || (sphereDetailV < 2)) { + sphereDetail(30); + } + beginShape(TRIANGLES); defaultEdges = false; normalMode = NORMAL_MODE_VERTEX; @@ -6627,13 +6634,16 @@ public class PGraphicsOpenGL extends PGraphics { @Override public void loadUniforms() { transformMatLoc = getUniformLoc("transform"); - if (transformMatLoc == -1) transformMatLoc = getUniformLoc("transformMatrix"); + if (transformMatLoc == -1) + transformMatLoc = getUniformLoc("transformMatrix"); modelviewMatLoc = getUniformLoc("modelview"); - if (modelviewMatLoc == -1) modelviewMatLoc = getUniformLoc("modelviewMatrix"); + if (modelviewMatLoc == -1) + modelviewMatLoc = getUniformLoc("modelviewMatrix"); projectionMatLoc = getUniformLoc("projection"); - if (projectionMatLoc == -1) projectionMatLoc = getUniformLoc("projectionMatrix"); + if (projectionMatLoc == -1) + projectionMatLoc = getUniformLoc("projectionMatrix"); viewportLoc = getUniformLoc("viewport"); bufferLoc = getUniformLoc("buffer"); @@ -6644,7 +6654,7 @@ public class PGraphicsOpenGL extends PGraphics { if (-1 < bufferLoc) { pgl.requestFBOLayer(); pgl.activeTexture(PGL.TEXTURE0 + bufferUnit); - pgCurrent.unbindFrontTexture(); + pg.unbindFrontTexture(); pgl.activeTexture(PGL.TEXTURE0); } @@ -6655,25 +6665,25 @@ public class PGraphicsOpenGL extends PGraphics { protected void setCommonUniforms() { if (-1 < transformMatLoc) { - pgCurrent.updateGLProjmodelview(); - setUniformMatrix(transformMatLoc, pgCurrent.glProjmodelview); + pg.updateGLProjmodelview(); + setUniformMatrix(transformMatLoc, pg.glProjmodelview); } if (-1 < modelviewMatLoc) { - pgCurrent.updateGLModelview(); - setUniformMatrix(modelviewMatLoc, pgCurrent.glModelview); + pg.updateGLModelview(); + setUniformMatrix(modelviewMatLoc, pg.glModelview); } if (-1 < projectionMatLoc) { - pgCurrent.updateGLProjection(); - setUniformMatrix(projectionMatLoc, pgCurrent.glProjection); + pg.updateGLProjection(); + setUniformMatrix(projectionMatLoc, pg.glProjection); } if (-1 < viewportLoc) { - float x = pgCurrent.viewport.get(0); - float y = pgCurrent.viewport.get(1); - float w = pgCurrent.viewport.get(2); - float h = pgCurrent.viewport.get(3); + float x = pg.viewport.get(0); + float y = pg.viewport.get(1); + float w = pg.viewport.get(2); + float h = pg.viewport.get(3); setUniformValue(viewportLoc, x, y, w, h); } @@ -6681,7 +6691,7 @@ public class PGraphicsOpenGL extends PGraphics { bufferUnit = super.getLastTexUnit() + 1; setUniformValue(bufferLoc, bufferUnit); pgl.activeTexture(PGL.TEXTURE0 + bufferUnit); - pgCurrent.bindFrontTexture(); + pg.bindFrontTexture(); } else { bufferUnit = -1; } @@ -6967,7 +6977,7 @@ public class PGraphicsOpenGL extends PGraphics { @Override public void bind() { super.bind(); - if (pgCurrent == null) { + if (pg == null) { setRenderer(PGraphicsOpenGL.pgCurrent); loadAttributes(); loadUniforms(); @@ -6980,8 +6990,8 @@ public class PGraphicsOpenGL extends PGraphics { if (-1 < normalLoc) pgl.enableVertexAttribArray(normalLoc); if (-1 < normalMatLoc) { - pgCurrent.updateGLNormal(); - setUniformMatrix(normalMatLoc, pgCurrent.glNormal); + pg.updateGLNormal(); + setUniformMatrix(normalMatLoc, pg.glNormal); } if (-1 < ambientLoc) pgl.enableVertexAttribArray(ambientLoc); @@ -6989,17 +6999,17 @@ public class PGraphicsOpenGL extends PGraphics { if (-1 < emissiveLoc) pgl.enableVertexAttribArray(emissiveLoc); if (-1 < shininessLoc) pgl.enableVertexAttribArray(shininessLoc); - int count = pgCurrent.lightCount; + int count = pg.lightCount; setUniformValue(lightCountLoc, count); if (0 < count) { - setUniformVector(lightPositionLoc, pgCurrent.lightPosition, 4, count); - setUniformVector(lightNormalLoc, pgCurrent.lightNormal, 3, count); - setUniformVector(lightAmbientLoc, pgCurrent.lightAmbient, 3, count); - setUniformVector(lightDiffuseLoc, pgCurrent.lightDiffuse, 3, count); - setUniformVector(lightSpecularLoc, pgCurrent.lightSpecular, 3, count); - setUniformVector(lightFalloffLoc, pgCurrent.lightFalloffCoefficients, + setUniformVector(lightPositionLoc, pg.lightPosition, 4, count); + setUniformVector(lightNormalLoc, pg.lightNormal, 3, count); + setUniformVector(lightAmbientLoc, pg.lightAmbient, 3, count); + setUniformVector(lightDiffuseLoc, pg.lightDiffuse, 3, count); + setUniformVector(lightSpecularLoc, pg.lightSpecular, 3, count); + setUniformVector(lightFalloffLoc, pg.lightFalloffCoefficients, 3, count); - setUniformVector(lightSpotLoc, pgCurrent.lightSpotParameters, 2, count); + setUniformVector(lightSpotLoc, pg.lightSpotParameters, 2, count); } } @@ -7086,7 +7096,7 @@ public class PGraphicsOpenGL extends PGraphics { @Override public void bind() { super.bind(); - if (pgCurrent == null) { + if (pg == null) { setRenderer(PGraphicsOpenGL.pgCurrent); loadAttributes(); loadUniforms(); @@ -7096,14 +7106,14 @@ public class PGraphicsOpenGL extends PGraphics { if (-1 < colorLoc) pgl.enableVertexAttribArray(colorLoc); if (-1 < directionLoc) pgl.enableVertexAttribArray(directionLoc); - if (pgCurrent.getHint(ENABLE_STROKE_PERSPECTIVE) && - pgCurrent.nonOrthoProjection()) { + if (pg.getHint(ENABLE_STROKE_PERSPECTIVE) && + pg.nonOrthoProjection()) { setUniformValue(perspectiveLoc, 1); } else { setUniformValue(perspectiveLoc, 0); } - if (pgCurrent.getHint(DISABLE_OPTIMIZED_STROKE)) { + if (pg.getHint(DISABLE_OPTIMIZED_STROKE)) { setUniformValue(scaleLoc, 1.0f, 1.0f, 1.0f); } else { float f = PGL.STROKE_DISPLACEMENT; @@ -7184,7 +7194,7 @@ public class PGraphicsOpenGL extends PGraphics { @Override public void bind() { super.bind(); - if (pgCurrent == null) { + if (pg == null) { setRenderer(PGraphicsOpenGL.pgCurrent); loadAttributes(); loadUniforms(); @@ -7194,8 +7204,8 @@ public class PGraphicsOpenGL extends PGraphics { if (-1 < colorLoc) pgl.enableVertexAttribArray(colorLoc); if (-1 < offsetLoc) pgl.enableVertexAttribArray(offsetLoc); - if (pgCurrent.getHint(ENABLE_STROKE_PERSPECTIVE) && - pgCurrent.nonOrthoProjection()) { + if (pg.getHint(ENABLE_STROKE_PERSPECTIVE) && + pg.nonOrthoProjection()) { setUniformValue(perspectiveLoc, 1); } else { setUniformValue(perspectiveLoc, 0); @@ -7232,24 +7242,24 @@ public class PGraphicsOpenGL extends PGraphics { // Input (raw) and Tessellated geometry, tessellator. - protected InGeometry newInGeometry(int mode) { - return new InGeometry(mode); + static protected InGeometry newInGeometry(PGraphicsOpenGL pg, int mode) { + return new InGeometry(pg, mode); } - protected TessGeometry newTessGeometry(int mode) { - return new TessGeometry(mode); + static protected TessGeometry newTessGeometry(PGraphicsOpenGL pg, int mode) { + return new TessGeometry(pg, mode); } - protected TexCache newTexCache() { + static protected TexCache newTexCache() { return new TexCache(); } // Holds an array of textures and the range of vertex // indices each texture applies to. - protected class TexCache { + static protected class TexCache { int size; PImage[] textures; int[] firstIndex; @@ -7367,7 +7377,7 @@ public class PGraphicsOpenGL extends PGraphics { // Stores the offsets and counts of indices and vertices // to render a piece of geometry that doesn't fit in a single // glDrawElements() call. - protected class IndexCache { + static protected class IndexCache { int size; int[] indexCount; int[] indexOffset; @@ -7472,23 +7482,14 @@ public class PGraphicsOpenGL extends PGraphics { // Holds the input vertices: xyz coordinates, fill/tint color, // normal, texture coordinates and stroke color and weight. - protected class InGeometry { + static protected class InGeometry { + PGraphicsOpenGL pg; int renderMode; + int vertexCount; + int codeCount; int edgeCount; - // Range of vertices that will be processed by the - // tessellator. They can be used in combination with the - // edges array to have the tessellator using only a specific - // range of vertices to generate fill geometry, while the - // line geometry will be read from the edge vertices, which - // could be completely different. - int firstVertex; - int lastVertex; - - int firstEdge; - int lastEdge; - float[] vertices; int[] colors; float[] normals; @@ -7496,8 +7497,11 @@ public class PGraphicsOpenGL extends PGraphics { int[] strokeColors; float[] strokeWeights; - // lines + // codes + int[] codes; boolean[] breaks; + + // Stroke edges int[][] edges; // Material properties @@ -7516,7 +7520,8 @@ public class PGraphicsOpenGL extends PGraphics { float shininessFactor; float normalX, normalY, normalZ; - InGeometry(int mode) { + InGeometry(PGraphicsOpenGL pg, int mode) { + this.pg = pg; renderMode = mode; allocate(); } @@ -7526,12 +7531,13 @@ public class PGraphicsOpenGL extends PGraphics { // Allocate/dispose void clear() { - vertexCount = firstVertex = lastVertex = 0; - edgeCount = firstEdge = lastEdge = 0; + vertexCount = 0; + codeCount = 0; + edgeCount = 0; } void clearEdges() { - edgeCount = firstEdge = lastEdge = 0; + edgeCount = 0; } void allocate() { @@ -7569,6 +7575,14 @@ public class PGraphicsOpenGL extends PGraphics { } } + void codeCheck() { + if (codeCount == codes.length) { + int newLen = codeCount << 1; + + expandCodes(newLen); + } + } + void edgeCheck() { if (edgeCount == edges.length) { int newLen = edgeCount << 1; @@ -7607,17 +7621,17 @@ public class PGraphicsOpenGL extends PGraphics { int getNumEdgeClosures() { int count = 0; - for (int i = firstEdge; i <= lastEdge; i++) { + for (int i = 0; i < edgeCount; i++) { if (edges[i][2] == EDGE_CLOSE) count++; } return count; } int getNumEdgeVertices(boolean bevel) { - int segVert = lastEdge - firstEdge + 1; + int segVert = edgeCount; int bevVert = 0; if (bevel) { - for (int i = firstEdge; i <= lastEdge; i++) { + for (int i = 0; i < edgeCount; i++) { int[] edge = edges[i]; if (edge[2] == EDGE_MIDDLE || edge[2] == EDGE_START) bevVert++; if (edge[2] == EDGE_CLOSE) segVert--; @@ -7629,10 +7643,10 @@ public class PGraphicsOpenGL extends PGraphics { } int getNumEdgeIndices(boolean bevel) { - int segInd = lastEdge - firstEdge + 1; + int segInd = edgeCount; int bevInd = 0; if (bevel) { - for (int i = firstEdge; i <= lastEdge; i++) { + for (int i = 0; i < edgeCount; i++) { int[] edge = edges[i]; if (edge[2] == EDGE_MIDDLE || edge[2] == EDGE_START) bevInd++; if (edge[2] == EDGE_CLOSE) segInd--; @@ -7738,6 +7752,12 @@ public class PGraphicsOpenGL extends PGraphics { shininess = temp; } + void expandCodes(int n) { + int temp[] = new int[n]; + PApplet.arrayCopy(codes, 0, temp, 0, codeCount); + codes = temp; + } + void expandBreaks(int n) { boolean temp[] = new boolean[n]; PApplet.arrayCopy(breaks, 0, temp, 0, vertexCount); @@ -7834,6 +7854,12 @@ public class PGraphicsOpenGL extends PGraphics { shininess = temp; } +// void trimCodes() { +// int temp[] = new int[vertexCount]; +// PApplet.arrayCopy(codes, 0, temp, 0, vertexCount); +// codes = temp; +// } + void trimBreaks() { boolean temp[] = new boolean[vertexCount]; PApplet.arrayCopy(breaks, 0, temp, 0, vertexCount); @@ -7850,8 +7876,12 @@ public class PGraphicsOpenGL extends PGraphics { // // Vertices + int addVertex(float x, float y, boolean brk) { + return addVertex(x, y, VERTEX, brk); + } + int addVertex(float x, float y, - int code) { + int code, boolean brk) { return addVertex(x, y, 0, fillColor, normalX, normalY, normalZ, @@ -7859,12 +7889,18 @@ public class PGraphicsOpenGL extends PGraphics { strokeColor, strokeWeight, ambientColor, specularColor, emissiveColor, shininessFactor, - code); + code, brk); } int addVertex(float x, float y, float u, float v, - int code) { + boolean brk) { + return addVertex(x, y, u, v, VERTEX, brk); + } + + int addVertex(float x, float y, + float u, float v, + int code, boolean brk) { return addVertex(x, y, 0, fillColor, normalX, normalY, normalZ, @@ -7872,11 +7908,15 @@ public class PGraphicsOpenGL extends PGraphics { strokeColor, strokeWeight, ambientColor, specularColor, emissiveColor, shininessFactor, - code); + code, brk); + } + + int addVertex(float x, float y, float z, boolean brk) { + return addVertex(x, y, z, VERTEX, brk); } int addVertex(float x, float y, float z, - int code) { + int code, boolean brk) { return addVertex(x, y, z, fillColor, normalX, normalY, normalZ, @@ -7884,12 +7924,18 @@ public class PGraphicsOpenGL extends PGraphics { strokeColor, strokeWeight, ambientColor, specularColor, emissiveColor, shininessFactor, - code); + code, brk); } int addVertex(float x, float y, float z, float u, float v, - int code) { + boolean brk) { + return addVertex(x, y, z, u, v, VERTEX, brk); + } + + int addVertex(float x, float y, float z, + float u, float v, + int code, boolean brk) { return addVertex(x, y, z, fillColor, normalX, normalY, normalZ, @@ -7897,7 +7943,7 @@ public class PGraphicsOpenGL extends PGraphics { strokeColor, strokeWeight, ambientColor, specularColor, emissiveColor, shininessFactor, - code); + code, brk); } int addVertex(float x, float y, float z, @@ -7906,12 +7952,10 @@ public class PGraphicsOpenGL extends PGraphics { float u, float v, int scolor, float sweight, int am, int sp, int em, float shine, - int code) { + int code, boolean brk) { vertexCheck(); int index; - curveVertexCount = 0; - index = 3 * vertexCount; vertices[index++] = x; vertices[index++] = y; @@ -7936,14 +7980,52 @@ public class PGraphicsOpenGL extends PGraphics { emissive[vertexCount] = PGL.javaToNativeARGB(em); shininess[vertexCount] = shine; - breaks[vertexCount] = code == BREAK; + breaks[vertexCount] = brk; + + if (code == BEZIER_VERTEX || code == QUADRATIC_VERTEX || + code == CURVE_VERTEX || (code == VERTEX && codes != null) || brk) { + if (codes == null) { + codes = new int[vertexCount]; + Arrays.fill(codes, 0, vertexCount, VERTEX); + } + + if (brk) { + codeCheck(); + codes[vertexCount] = BREAK; + codeCount++; + } + + if (code != -1) { + codeCheck(); + codes[vertexCount] = code; + codeCount++; + } + } - lastVertex = vertexCount; vertexCount++; - return lastVertex; + return vertexCount - 1; } + public void addBezierVertex(float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4, boolean brk) { + addVertex(x2, y2, z2, BEZIER_VERTEX, brk); + addVertex(x3, y3, z3, -1, false); + addVertex(x4, y4, z4, -1, false); + } + + public void addQuadraticVertex(float cx, float cy, float cz, + float x3, float y3, float z3, boolean brk) { + addVertex(cx, cy, cz, QUADRATIC_VERTEX, brk); + addVertex(x3, y3, z3, -1, false); + } + + public void addCurveVertex(float x, float y, float z, boolean brk) { + addVertex(x, y, z, CURVE_VERTEX, brk); + } + + /* void addBezierVertex(float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4, @@ -7957,7 +8039,7 @@ public class PGraphicsOpenGL extends PGraphics { void addBezierVertex(float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4, - boolean fill, boolean stroke, int detail, int code, + boolean fill, boolean stroke, int detail, int code, // this should be break flag int shape) { bezierInitCheck(); bezierVertexCheck(shape, vertexCount); @@ -7987,11 +8069,17 @@ public class PGraphicsOpenGL extends PGraphics { addVertex(x1, y1, z1, j == 0 && code == BREAK ? BREAK : VERTEX); } } + */ + /* public void addQuadraticVertex(float cx, float cy, float cz, float x3, float y3, float z3, boolean fill, boolean stroke, int detail, int code) { + addVertex(cx, cy, cz, QUADRATIC_VERTEX, brk); + addVertex(x3, y3, z3, QUADRATIC_VERTEX, false); + + addQuadraticVertex(cx, cy, cz, x3, y3, z3, fill, stroke, detail, code, POLYGON); @@ -8010,7 +8098,9 @@ public class PGraphicsOpenGL extends PGraphics { x3, y3, z3, fill, stroke, detail, code, shape); } + */ + /* void addCurveVertex(float x, float y, float z, boolean fill, boolean stroke, int detail, int code) { addCurveVertex(x, y, z, @@ -8078,6 +8168,7 @@ public class PGraphicsOpenGL extends PGraphics { curveVertexCount = savedCount; } +*/ // Returns the vertex data in the PGraphics double array format. float[][] getVertexData() { @@ -8112,6 +8203,27 @@ public class PGraphicsOpenGL extends PGraphics { return data; } + boolean hasBezierVertex() { + for (int i = 0; i < codeCount; i++) { + if (codes[i] == BEZIER_VERTEX) return true; + } + return false; + } + + boolean hasQuadraticVertex() { + for (int i = 0; i < codeCount; i++) { + if (codes[i] == QUADRATIC_VERTEX) return true; + } + return false; + } + + boolean hasCurveVertex() { + for (int i = 0; i < codeCount; i++) { + if (codes[i] == CURVE_VERTEX) return true; + } + return false; + } + // ----------------------------------------------------------------- // // Edges @@ -8130,10 +8242,9 @@ public class PGraphicsOpenGL extends PGraphics { // 3 = isolated edge (start, end) edge[2] = (start ? 1 : 0) + 2 * (end ? 1 : 0); - lastEdge = edgeCount; edgeCount++; - return lastEdge; + return edgeCount - 1; } int closeEdge(int i, int j) { @@ -8144,14 +8255,13 @@ public class PGraphicsOpenGL extends PGraphics { edge[1] = j; edge[2] = -1; - lastEdge = edgeCount; edgeCount++; - return lastEdge; + return edgeCount - 1; } void addTrianglesEdges() { - for (int i = 0; i < (lastVertex - firstVertex + 1) / 3; i++) { + for (int i = 0; i < vertexCount / 3; i++) { int i0 = 3 * i + 0; int i1 = 3 * i + 1; int i2 = 3 * i + 2; @@ -8164,8 +8274,8 @@ public class PGraphicsOpenGL extends PGraphics { } void addTriangleFanEdges() { - for (int i = firstVertex + 1; i < lastVertex; i++) { - int i0 = firstVertex; + for (int i = 1; i < vertexCount - 1; i++) { + int i0 = 0; int i1 = i; int i2 = i + 1; @@ -8177,7 +8287,7 @@ public class PGraphicsOpenGL extends PGraphics { } void addTriangleStripEdges() { - for (int i = firstVertex + 1; i < lastVertex; i++) { + for (int i = 1; i < vertexCount - 1; i++) { int i0 = i; int i1, i2; if (i % 2 == 0) { @@ -8196,7 +8306,7 @@ public class PGraphicsOpenGL extends PGraphics { } void addQuadsEdges() { - for (int i = 0; i < (lastVertex - firstVertex + 1) / 4; i++) { + for (int i = 0; i < vertexCount / 4; i++) { int i0 = 4 * i + 0; int i1 = 4 * i + 1; int i2 = 4 * i + 2; @@ -8211,11 +8321,11 @@ public class PGraphicsOpenGL extends PGraphics { } void addQuadStripEdges() { - for (int qd = 1; qd < (lastVertex - firstVertex + 1) / 2; qd++) { - int i0 = firstVertex + 2 * (qd - 1); - int i1 = firstVertex + 2 * (qd - 1) + 1; - int i2 = firstVertex + 2 * qd + 1; - int i3 = firstVertex + 2 * qd; + for (int qd = 1; qd < vertexCount / 2; qd++) { + int i0 = 2 * (qd - 1); + int i1 = 2 * (qd - 1) + 1; + int i2 = 2 * qd + 1; + int i3 = 2 * qd; addEdge(i0, i1, true, false); addEdge(i1, i2, false, false); @@ -8226,9 +8336,11 @@ public class PGraphicsOpenGL extends PGraphics { } void addPolygonEdges(boolean closed) { - int start = firstVertex; + // TODO: need to expand bezier, quadratic and curve vertices...crap. + + int start = 0; boolean begin = true; - for (int i = firstVertex + 1; i <= lastVertex; i++) { + for (int i = 1; i <= vertexCount - 1; i++) { if (breaks[i]) { if (closed) { // Closing previous contour. @@ -8240,7 +8352,7 @@ public class PGraphicsOpenGL extends PGraphics { start = i; begin = true; } else { - if (i == lastVertex) { + if (i == vertexCount - 1) { if (closed && start + 1 < i) { // Closing the end of the last contour, if it // has more than 1 segment. @@ -8253,7 +8365,7 @@ public class PGraphicsOpenGL extends PGraphics { } } else { - if (i < lastVertex && breaks[i + 1] && !closed) { + if ((i < vertexCount - 1) && breaks[i + 1] && !closed) { // A new contour starts at the next vertex and // the polygon is not closed, so this is the last // segment of the current contour. @@ -8267,6 +8379,8 @@ public class PGraphicsOpenGL extends PGraphics { begin = false; } } + + } // ----------------------------------------------------------------- @@ -8328,7 +8442,7 @@ public class PGraphicsOpenGL extends PGraphics { } void calcTrianglesNormals() { - for (int i = 0; i < (lastVertex - firstVertex + 1) / 3; i++) { + for (int i = 0; i < vertexCount / 3; i++) { int i0 = 3 * i + 0; int i1 = 3 * i + 1; int i2 = 3 * i + 2; @@ -8338,8 +8452,8 @@ public class PGraphicsOpenGL extends PGraphics { } void calcTriangleFanNormals() { - for (int i = firstVertex + 1; i < lastVertex; i++) { - int i0 = firstVertex; + for (int i = 1; i < vertexCount - 1; i++) { + int i0 = 0; int i1 = i; int i2 = i + 1; @@ -8348,7 +8462,7 @@ public class PGraphicsOpenGL extends PGraphics { } void calcTriangleStripNormals() { - for (int i = firstVertex + 1; i < lastVertex; i++) { + for (int i = 1; i < vertexCount - 1; i++) { int i1 = i; int i0, i2; if (i % 2 == 0) { @@ -8365,7 +8479,7 @@ public class PGraphicsOpenGL extends PGraphics { } void calcQuadsNormals() { - for (int i = 0; i < (lastVertex - firstVertex + 1) / 4; i++) { + for (int i = 0; i < vertexCount / 4; i++) { int i0 = 4 * i + 0; int i1 = 4 * i + 1; int i2 = 4 * i + 2; @@ -8377,11 +8491,11 @@ public class PGraphicsOpenGL extends PGraphics { } void calcQuadStripNormals() { - for (int qd = 1; qd < (lastVertex - firstVertex + 1) / 2; qd++) { - int i0 = firstVertex + 2 * (qd - 1); - int i1 = firstVertex + 2 * (qd - 1) + 1; - int i2 = firstVertex + 2 * qd; - int i3 = firstVertex + 2 * qd + 1; + for (int qd = 1; qd < vertexCount / 2; qd++) { + int i0 = 2 * (qd - 1); + int i1 = 2 * (qd - 1) + 1; + int i2 = 2 * qd; + int i3 = 2 * qd + 1; calcTriangleNormal(i0, i3, i1); calcTriangleNormal(i0, i2, i3); @@ -8411,14 +8525,14 @@ public class PGraphicsOpenGL extends PGraphics { } void addPoint(float x, float y, float z, boolean fill, boolean stroke) { - addVertex(x, y, z, VERTEX); + addVertex(x, y, z, VERTEX, true); } void addLine(float x1, float y1, float z1, float x2, float y2, float z2, boolean fill, boolean stroke) { - int idx1 = addVertex(x1, y1, z1, VERTEX); - int idx2 = addVertex(x2, y2, z2, VERTEX); + int idx1 = addVertex(x1, y1, z1, VERTEX, true); + int idx2 = addVertex(x2, y2, z2, VERTEX, false); if (stroke) addEdge(idx1, idx2, true, true); } @@ -8426,9 +8540,9 @@ public class PGraphicsOpenGL extends PGraphics { float x2, float y2, float z2, float x3, float y3, float z3, boolean fill, boolean stroke) { - int idx1 = addVertex(x1, y1, z1, VERTEX); - int idx2 = addVertex(x2, y2, z2, VERTEX); - int idx3 = addVertex(x3, y3, z3, VERTEX); + int idx1 = addVertex(x1, y1, z1, VERTEX, true); + int idx2 = addVertex(x2, y2, z2, VERTEX, false); + int idx3 = addVertex(x3, y3, z3, VERTEX, false); if (stroke) { addEdge(idx1, idx2, true, false); addEdge(idx2, idx3, false, false); @@ -8441,11 +8555,11 @@ public class PGraphicsOpenGL extends PGraphics { float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4, - boolean fill, boolean stroke) { - int idx1 = addVertex(x1, y1, z1, 0, 0, VERTEX); - int idx2 = addVertex(x2, y2, z2, 1, 0, VERTEX); - int idx3 = addVertex(x3, y3, z3, 1, 1, VERTEX); - int idx4 = addVertex(x4, y4, z4, 0, 1, VERTEX); + boolean stroke) { + int idx1 = addVertex(x1, y1, z1, 0, 0, VERTEX, true); + int idx2 = addVertex(x2, y2, z2, 1, 0, VERTEX, false); + int idx3 = addVertex(x3, y3, z3, 1, 1, VERTEX, false); + int idx4 = addVertex(x4, y4, z4, 0, 1, VERTEX, false); if (stroke) { addEdge(idx1, idx2, true, false); addEdge(idx2, idx3, false, false); @@ -8456,44 +8570,40 @@ public class PGraphicsOpenGL extends PGraphics { } void addRect(float a, float b, float c, float d, - boolean fill, boolean stroke) { + boolean stroke) { addQuad(a, b, 0, c, b, 0, c, d, 0, a, d, 0, - fill, stroke); + stroke); } void addRect(float a, float b, float c, float d, float tl, float tr, float br, float bl, - boolean fill, boolean stroke, int detail) { + boolean stroke) { if (nonZero(tr)) { - addVertex(c-tr, b, VERTEX); - addQuadraticVertex(c, b, 0, c, b+tr, 0, - fill, stroke, detail, VERTEX); + addVertex(c-tr, b, VERTEX, true); + addQuadraticVertex(c, b, 0, c, b+tr, 0, false); } else { - addVertex(c, b, VERTEX); + addVertex(c, b, VERTEX, true); } if (nonZero(br)) { - addVertex(c, d-br, VERTEX); - addQuadraticVertex(c, d, 0, c-br, d, 0, - fill, stroke, detail, VERTEX); + addVertex(c, d-br, VERTEX, false); + addQuadraticVertex(c, d, 0, c-br, d, 0, false); } else { - addVertex(c, d, VERTEX); + addVertex(c, d, VERTEX, false); } if (nonZero(bl)) { - addVertex(a+bl, d, VERTEX); - addQuadraticVertex(a, d, 0, a, d-bl, 0, - fill, stroke, detail, VERTEX); + addVertex(a+bl, d, VERTEX, false); + addQuadraticVertex(a, d, 0, a, d-bl, 0, false); } else { - addVertex(a, d, VERTEX); + addVertex(a, d, VERTEX, false); } if (nonZero(tl)) { - addVertex(a, b+tl, VERTEX); - addQuadraticVertex(a, b, 0, a+tl, b, 0, - fill, stroke, detail, VERTEX); + addVertex(a, b+tl, VERTEX, false); + addQuadraticVertex(a, b, 0, a+tl, b, 0, false); } else { - addVertex(a, b, VERTEX); + addVertex(a, b, VERTEX, false); } if (stroke) addPolygonEdges(true); @@ -8508,10 +8618,10 @@ public class PGraphicsOpenGL extends PGraphics { float centerY = y + radiusV; // should call screenX/Y using current renderer. - float sx1 = pgCurrent.screenX(x, y); - float sy1 = pgCurrent.screenY(x, y); - float sx2 = pgCurrent.screenX(x + w, y + h); - float sy2 = pgCurrent.screenY(x + w, y + h); + float sx1 = pg.screenX(x, y); + float sy1 = pg.screenY(x, y); + float sx2 = pg.screenX(x + w, y + h); + float sy2 = pg.screenY(x + w, y + h); int accuracy = PApplet.min(MAX_POINT_ACCURACY, PApplet.max(MIN_POINT_ACCURACY, @@ -8520,7 +8630,7 @@ public class PGraphicsOpenGL extends PGraphics { float inc = (float) SINCOS_LENGTH / accuracy; if (fill) { - addVertex(centerX, centerY, VERTEX); + addVertex(centerX, centerY, VERTEX, true); } int idx0, pidx, idx; idx0 = pidx = idx = 0; @@ -8528,7 +8638,7 @@ public class PGraphicsOpenGL extends PGraphics { for (int i = 0; i < accuracy; i++) { idx = addVertex(centerX + cosLUT[(int) val] * radiusH, centerY + sinLUT[(int) val] * radiusV, - VERTEX); + VERTEX, i == 0 && !fill); val = (val + inc) % SINCOS_LENGTH; if (0 < i) { @@ -8542,7 +8652,7 @@ public class PGraphicsOpenGL extends PGraphics { // Back to the beginning addVertex(centerX + cosLUT[0] * radiusH, centerY + sinLUT[0] * radiusV, - VERTEX); + VERTEX, false); if (stroke) { addEdge(idx, idx0, false, false); closeEdge(idx, idx0); @@ -8563,7 +8673,7 @@ public class PGraphicsOpenGL extends PGraphics { int stopLUT = (int) (0.5f + (stop / TWO_PI) * SINCOS_LENGTH); if (fill) { - addVertex(centerX, centerY, VERTEX); + addVertex(centerX, centerY, VERTEX, true); } int increment = 1; // what's a good algorithm? stopLUT - startLUT; @@ -8575,7 +8685,7 @@ public class PGraphicsOpenGL extends PGraphics { if (ii < 0) ii += SINCOS_LENGTH; idx = addVertex(centerX + cosLUT[ii] * hr, centerY + sinLUT[ii] * vr, - VERTEX); + VERTEX, i == startLUT && !fill); if (stroke) { if (arcMode == PIE) { @@ -8592,7 +8702,7 @@ public class PGraphicsOpenGL extends PGraphics { // draw last point explicitly for accuracy idx = addVertex(centerX + cosLUT[stopLUT % SINCOS_LENGTH] * hr, centerY + sinLUT[stopLUT % SINCOS_LENGTH] * vr, - VERTEX); + VERTEX, false); if (stroke) { if (arcMode == PIE) { addEdge(idx, idx0, false, false); @@ -8607,7 +8717,7 @@ public class PGraphicsOpenGL extends PGraphics { if (ii < 0) ii += SINCOS_LENGTH; idx = addVertex(centerX + cosLUT[ii] * hr, centerY + sinLUT[ii] * vr, - VERTEX); + VERTEX, false); if (stroke && arcMode == CHORD) { addEdge(pidx, idx, false, true); } @@ -8624,10 +8734,10 @@ public class PGraphicsOpenGL extends PGraphics { if (fill || stroke) { // front face setNormal(0, 0, 1); - idx1 = addVertex(x1, y1, z1, 0, 0, VERTEX); - idx2 = addVertex(x2, y1, z1, 1, 0, VERTEX); - idx3 = addVertex(x2, y2, z1, 1, 1, VERTEX); - idx4 = addVertex(x1, y2, z1, 0, 1, VERTEX); + idx1 = addVertex(x1, y1, z1, 0, 0, VERTEX, true); + idx2 = addVertex(x2, y1, z1, 1, 0, VERTEX, false); + idx3 = addVertex(x2, y2, z1, 1, 1, VERTEX, false); + idx4 = addVertex(x1, y2, z1, 0, 1, VERTEX, false); if (stroke) { addEdge(idx1, idx2, true, false); addEdge(idx2, idx3, false, false); @@ -8638,10 +8748,10 @@ public class PGraphicsOpenGL extends PGraphics { // back face setNormal(0, 0, -1); - idx1 = addVertex(x2, y1, z2, 0, 0, VERTEX); - idx2 = addVertex(x1, y1, z2, 1, 0, VERTEX); - idx3 = addVertex(x1, y2, z2, 1, 1, VERTEX); - idx4 = addVertex(x2, y2, z2, 0, 1, VERTEX); + idx1 = addVertex(x2, y1, z2, 0, 0, VERTEX, false); + idx2 = addVertex(x1, y1, z2, 1, 0, VERTEX, false); + idx3 = addVertex(x1, y2, z2, 1, 1, VERTEX, false); + idx4 = addVertex(x2, y2, z2, 0, 1, VERTEX, false); if (stroke) { addEdge(idx1, idx2, true, false); addEdge(idx2, idx3, false, false); @@ -8652,10 +8762,10 @@ public class PGraphicsOpenGL extends PGraphics { // right face setNormal(1, 0, 0); - idx1 = addVertex(x2, y1, z1, 0, 0, VERTEX); - idx2 = addVertex(x2, y1, z2, 1, 0, VERTEX); - idx3 = addVertex(x2, y2, z2, 1, 1, VERTEX); - idx4 = addVertex(x2, y2, z1, 0, 1, VERTEX); + idx1 = addVertex(x2, y1, z1, 0, 0, VERTEX, false); + idx2 = addVertex(x2, y1, z2, 1, 0, VERTEX, false); + idx3 = addVertex(x2, y2, z2, 1, 1, VERTEX, false); + idx4 = addVertex(x2, y2, z1, 0, 1, VERTEX, false); if (stroke) { addEdge(idx1, idx2, true, false); addEdge(idx2, idx3, false, false); @@ -8666,10 +8776,10 @@ public class PGraphicsOpenGL extends PGraphics { // left face setNormal(-1, 0, 0); - idx1 = addVertex(x1, y1, z2, 0, 0, VERTEX); - idx2 = addVertex(x1, y1, z1, 1, 0, VERTEX); - idx3 = addVertex(x1, y2, z1, 1, 1, VERTEX); - idx4 = addVertex(x1, y2, z2, 0, 1, VERTEX); + idx1 = addVertex(x1, y1, z2, 0, 0, VERTEX, false); + idx2 = addVertex(x1, y1, z1, 1, 0, VERTEX, false); + idx3 = addVertex(x1, y2, z1, 1, 1, VERTEX, false); + idx4 = addVertex(x1, y2, z2, 0, 1, VERTEX, false); if (stroke) { addEdge(idx1, idx2, true, false); addEdge(idx2, idx3, false, false); @@ -8680,10 +8790,10 @@ public class PGraphicsOpenGL extends PGraphics { // top face setNormal(0, 1, 0); - idx1 = addVertex(x1, y1, z2, 0, 0, VERTEX); - idx2 = addVertex(x2, y1, z2, 1, 0, VERTEX); - idx3 = addVertex(x2, y1, z1, 1, 1, VERTEX); - idx4 = addVertex(x1, y1, z1, 0, 1, VERTEX); + idx1 = addVertex(x1, y1, z2, 0, 0, VERTEX, false); + idx2 = addVertex(x2, y1, z2, 1, 0, VERTEX, false); + idx3 = addVertex(x2, y1, z1, 1, 1, VERTEX, false); + idx4 = addVertex(x1, y1, z1, 0, 1, VERTEX, false); if (stroke) { addEdge(idx1, idx2, true, false); addEdge(idx2, idx3, false, false); @@ -8694,10 +8804,10 @@ public class PGraphicsOpenGL extends PGraphics { // bottom face setNormal(0, -1, 0); - idx1 = addVertex(x1, y2, z1, 0, 0, VERTEX); - idx2 = addVertex(x2, y2, z1, 1, 0, VERTEX); - idx3 = addVertex(x2, y2, z2, 1, 1, VERTEX); - idx4 = addVertex(x1, y2, z2, 0, 1, VERTEX); + idx1 = addVertex(x1, y2, z1, 0, 0, VERTEX, false); + idx2 = addVertex(x2, y2, z1, 1, 0, VERTEX, false); + idx3 = addVertex(x2, y2, z2, 1, 1, VERTEX, false); + idx4 = addVertex(x1, y2, z2, 0, 1, VERTEX, false); if (stroke) { addEdge(idx1, idx2, true, false); addEdge(idx2, idx3, false, false); @@ -8712,13 +8822,6 @@ public class PGraphicsOpenGL extends PGraphics { // any vertex or edge. int[] addSphere(float r, int detailU, int detailV, boolean fill, boolean stroke) { - if ((detailU < 3) || (detailV < 2)) { - sphereDetail(30); - detailU = detailV = 30; - } else { - sphereDetail(detailU, detailV); - } - int nind = 3 * detailU + (6 * detailU + 3) * (detailV - 2) + 3 * detailU; int[] indices = new int[nind]; @@ -8738,21 +8841,23 @@ public class PGraphicsOpenGL extends PGraphics { u = 1; v = 1; for (int i = 0; i < detailU; i++) { setNormal(0, 1, 0); - addVertex(0, r, 0, u , v, VERTEX); + addVertex(0, r, 0, u , v, VERTEX, true); u -= du; } vertCount = detailU; vert0 = vertCount; u = 1; v -= dv; for (int i = 0; i < detailU; i++) { - setNormal(sphereX[i], sphereY[i], sphereZ[i]); - addVertex(r * sphereX[i], r *sphereY[i], r * sphereZ[i], u , v, VERTEX); + setNormal(pg.sphereX[i], pg.sphereY[i], pg.sphereZ[i]); + addVertex(r*pg.sphereX[i], r*pg.sphereY[i], r*pg.sphereZ[i], u , v, + VERTEX, false); u -= du; } vertCount += detailU; vert1 = vertCount; - setNormal(sphereX[0], sphereY[0], sphereZ[0]); - addVertex(r * sphereX[0], r * sphereY[0], r * sphereZ[0], u, v, VERTEX); + setNormal(pg.sphereX[0], pg.sphereY[0], pg.sphereZ[0]); + addVertex(r*pg.sphereX[0], r*pg.sphereY[0], r*pg.sphereZ[0], u, v, + VERTEX, false); vertCount++; for (int i = 0; i < detailU; i++) { @@ -8777,16 +8882,16 @@ public class PGraphicsOpenGL extends PGraphics { u = 1; v -= dv; for (int i = 0; i < detailU; i++) { int ioff = offset + i; - setNormal(sphereX[ioff], sphereY[ioff], sphereZ[ioff]); - addVertex(r * sphereX[ioff], r *sphereY[ioff], r * sphereZ[ioff], - u , v, VERTEX); + setNormal(pg.sphereX[ioff], pg.sphereY[ioff], pg.sphereZ[ioff]); + addVertex(r*pg.sphereX[ioff], r*pg.sphereY[ioff], r*pg.sphereZ[ioff], + u , v, VERTEX, false); u -= du; } vertCount += detailU; vert1 = vertCount; - setNormal(sphereX[offset], sphereY[offset], sphereZ[offset]); - addVertex(r * sphereX[offset], r * sphereY[offset], r * sphereZ[offset], - u, v, VERTEX); + setNormal(pg.sphereX[offset], pg.sphereY[offset], pg.sphereZ[offset]); + addVertex(r*pg.sphereX[offset], r*pg.sphereY[offset], r*pg.sphereZ[offset], + u, v, VERTEX, false); vertCount++; for (int i = 0; i < detailU; i++) { @@ -8823,7 +8928,7 @@ public class PGraphicsOpenGL extends PGraphics { u = 1; v = 0; for (int i = 0; i < detailU; i++) { setNormal(0, -1, 0); - addVertex(0, -r, 0, u , v, VERTEX); + addVertex(0, -r, 0, u , v, VERTEX, false); u -= du; } vertCount += detailU; @@ -8847,8 +8952,9 @@ public class PGraphicsOpenGL extends PGraphics { // Holds tessellated data for polygon, line and point geometry. - protected class TessGeometry { + static protected class TessGeometry { int renderMode; + PGraphicsOpenGL pg; // Tessellated polygon data int polyVertexCount; @@ -8919,7 +9025,8 @@ public class PGraphicsOpenGL extends PGraphics { float[] pointOffsets; short[] pointIndices; - TessGeometry(int mode) { + TessGeometry(PGraphicsOpenGL pg, int mode) { + this.pg = pg; renderMode = mode; allocate(); } @@ -9721,8 +9828,8 @@ public class PGraphicsOpenGL extends PGraphics { float y = in.vertices[index++]; float z = in.vertices[index ]; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL) { - PMatrix3D mm = modelview; + if (renderMode == IMMEDIATE && pg.flushMode == FLUSH_WHEN_FULL) { + PMatrix3D mm = pg.modelview; index = 4 * tessIdx; pointVertices[index++] = x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03; @@ -9752,8 +9859,8 @@ public class PGraphicsOpenGL extends PGraphics { float y0 = in.vertices[index++]; float z0 = in.vertices[index ]; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL) { - PMatrix3D mm = modelview; + if (renderMode == IMMEDIATE && pg.flushMode == FLUSH_WHEN_FULL) { + PMatrix3D mm = pg.modelview; index = 4 * tessIdx; lineVertices[index++] = x0*mm.m00 + y0*mm.m01 + z0*mm.m02 + mm.m03; @@ -9796,8 +9903,8 @@ public class PGraphicsOpenGL extends PGraphics { float dy = y1 - y0; float dz = z1 - z0; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL) { - PMatrix3D mm = modelview; + if (renderMode == IMMEDIATE && pg.flushMode == FLUSH_WHEN_FULL) { + PMatrix3D mm = pg.modelview; index = 4 * tessIdx; lineVertices[index++] = x0*mm.m00 + y0*mm.m01 + z0*mm.m02 + mm.m03; @@ -9862,9 +9969,9 @@ public class PGraphicsOpenGL extends PGraphics { boolean clampXY) { int index; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL) { - PMatrix3D mm = modelview; - PMatrix3D nm = modelviewInv; + if (renderMode == IMMEDIATE && pg.flushMode == FLUSH_WHEN_FULL) { + PMatrix3D mm = pg.modelview; + PMatrix3D nm = pg.modelviewInv; index = 4 * tessIdx; if (clampXY) { @@ -9910,7 +10017,7 @@ public class PGraphicsOpenGL extends PGraphics { } void addPolyVertices(InGeometry in, boolean clampXY) { - addPolyVertices(in, in.firstVertex, in.lastVertex, clampXY); + addPolyVertices(in, 0, in.vertexCount - 1, clampXY); } void addPolyVertex(InGeometry in, int i, boolean clampXY) { @@ -9923,9 +10030,9 @@ public class PGraphicsOpenGL extends PGraphics { polyVertexCheck(nvert); - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL) { - PMatrix3D mm = modelview; - PMatrix3D nm = modelviewInv; + if (renderMode == IMMEDIATE && pg.flushMode == FLUSH_WHEN_FULL) { + PMatrix3D mm = pg.modelview; + PMatrix3D nm = pg.modelviewInv; for (int i = 0; i < nvert; i++) { int inIdx = i0 + i; @@ -10220,7 +10327,7 @@ public class PGraphicsOpenGL extends PGraphics { // Generates tessellated geometry given a batch of input vertices. // Generates tessellated geometry given a batch of input vertices. - protected class Tessellator { + static protected class Tessellator { InGeometry in; TessGeometry tess; TexCache texCache; @@ -10243,6 +10350,7 @@ public class PGraphicsOpenGL extends PGraphics { PMatrix transform; float transformScale; boolean is2D, is3D; + protected PGraphicsOpenGL pg; int[] rawIndices; int rawSize; @@ -10285,6 +10393,13 @@ public class PGraphicsOpenGL extends PGraphics { this.fill = fill; } + void setTexCache(TexCache texCache, PImage prevTexImage, + PImage newTexImage) { + this.texCache = texCache; + this.prevTexImage = prevTexImage; + this.newTexImage = newTexImage; + } + void setStroke(boolean stroke) { this.stroke = stroke; } @@ -10297,23 +10412,20 @@ public class PGraphicsOpenGL extends PGraphics { this.strokeWeight = weight; } - void setStrokeJoin(int strokeJoin) { - this.strokeJoin = strokeJoin; - } - void setStrokeCap(int strokeCap) { this.strokeCap = strokeCap; } + void setStrokeJoin(int strokeJoin) { + this.strokeJoin = strokeJoin; + } + void setAccurate2DStrokes(boolean accurate) { this.accurate2DStrokes = accurate; } - void setTexCache(TexCache texCache, PImage prevTexImage, - PImage newTexImage) { - this.texCache = texCache; - this.prevTexImage = prevTexImage; - this.newTexImage = newTexImage; + protected void setRenderer(PGraphicsOpenGL pg) { + this.pg = pg; } void set3D(boolean value) { @@ -10344,7 +10456,7 @@ public class PGraphicsOpenGL extends PGraphics { } void tessellateRoundPoints() { - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (stroke && 1 <= nInVert) { // Each point generates a separate triangle fan. // The number of triangles of each fan depends on the @@ -10379,7 +10491,7 @@ public class PGraphicsOpenGL extends PGraphics { IndexCache cache = tess.pointIndexCache; int index = in.renderMode == RETAINED ? cache.addNew() : cache.getLast(); firstPointIndexCache = index; - for (int i = in.firstVertex; i <= in.lastVertex; i++) { + for (int i = 0; i < in.vertexCount; i++) { // Creating the triangle fan for each input vertex. int count = cache.vertexCount[index]; @@ -10439,7 +10551,7 @@ public class PGraphicsOpenGL extends PGraphics { IndexCache cache = tess.polyIndexCache; int index = in.renderMode == RETAINED ? cache.addNew() : cache.getLast(); firstPointIndexCache = index; - for (int i = in.firstVertex; i <= in.lastVertex; i++) { + for (int i = 0; i < in.vertexCount; i++) { int count = cache.vertexCount[index]; if (PGL.MAX_VERTEX_INDEX1 <= count + nPtVert) { // We need to start a new index block for this point. @@ -10482,7 +10594,7 @@ public class PGraphicsOpenGL extends PGraphics { } void tessellateSquarePoints() { - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (stroke && 1 <= nInVert) { updateTex(); int quadCount = nInVert; // Each point generates a separate quad. @@ -10512,7 +10624,7 @@ public class PGraphicsOpenGL extends PGraphics { IndexCache cache = tess.pointIndexCache; int index = in.renderMode == RETAINED ? cache.addNew() : cache.getLast(); firstPointIndexCache = index; - for (int i = in.firstVertex; i <= in.lastVertex; i++) { + for (int i = 0; i < in.vertexCount; i++) { int nvert = 5; int count = cache.vertexCount[index]; if (PGL.MAX_VERTEX_INDEX1 <= count + nvert) { @@ -10567,7 +10679,7 @@ public class PGraphicsOpenGL extends PGraphics { IndexCache cache = tess.polyIndexCache; int index = in.renderMode == RETAINED ? cache.addNew() : cache.getLast(); firstPointIndexCache = index; - for (int i = in.firstVertex; i <= in.lastVertex; i++) { + for (int i = 0; i < in.vertexCount; i++) { int nvert = 5; int count = cache.vertexCount[index]; if (PGL.MAX_VERTEX_INDEX1 <= count + nvert) { @@ -10607,7 +10719,7 @@ public class PGraphicsOpenGL extends PGraphics { boolean clamp2D() { return is2D && tess.renderMode == IMMEDIATE && - zero(modelview.m01) && zero(modelview.m10); + zero(pg.modelview.m01) && zero(pg.modelview.m10); } boolean clampSquarePoints2D() { @@ -10619,7 +10731,7 @@ public class PGraphicsOpenGL extends PGraphics { // Line tessellation void tessellateLines() { - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (stroke && 2 <= nInVert) { updateTex(); int lineCount = nInVert / 2; // Each individual line is formed by two consecutive input vertices. @@ -10640,15 +10752,14 @@ public class PGraphicsOpenGL extends PGraphics { // require 3 indices to specify their connectivities. int nind = lineCount * 2 * 3; - int first = in.firstVertex; tess.lineVertexCheck(nvert); tess.lineIndexCheck(nind); int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast(); firstLineIndexCache = index; for (int ln = 0; ln < lineCount; ln++) { - int i0 = first + 2 * ln + 0; - int i1 = first + 2 * ln + 1; + int i0 = 2 * ln + 0; + int i1 = 2 * ln + 1; index = addLineSegment3D(i0, i1, index, null, false); } lastLineIndexCache = index; @@ -10658,7 +10769,6 @@ public class PGraphicsOpenGL extends PGraphics { int nvert = lineCount * 4; int nind = lineCount * 2 * 3; - int first = in.firstVertex; if (noCapsJoins(nvert)) { tess.polyVertexCheck(nvert); tess.polyIndexCheck(nind); @@ -10668,16 +10778,16 @@ public class PGraphicsOpenGL extends PGraphics { if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index. boolean clamp = clampLines2D(lineCount); for (int ln = 0; ln < lineCount; ln++) { - int i0 = first + 2 * ln + 0; - int i1 = first + 2 * ln + 1; + int i0 = 2 * ln + 0; + int i1 = 2 * ln + 1; index = addLineSegment2D(i0, i1, index, false, clamp); } lastLineIndexCache = lastPolyIndexCache = index; } else { // full stroking algorithm LinePath path = new LinePath(LinePath.WIND_NON_ZERO); for (int ln = 0; ln < lineCount; ln++) { - int i0 = first + 2 * ln + 0; - int i1 = first + 2 * ln + 1; + int i0 = 2 * ln + 0; + int i1 = 2 * ln + 1; path.moveTo(in.vertices[3 * i0 + 0], in.vertices[3 * i0 + 1], in.strokeColors[i0]); path.lineTo(in.vertices[3 * i1 + 0], in.vertices[3 * i1 + 1], @@ -10690,10 +10800,9 @@ public class PGraphicsOpenGL extends PGraphics { boolean clampLines2D(int lineCount) { boolean res = clamp2D(); if (res) { - int first = in.firstVertex; for (int ln = 0; ln < lineCount; ln++) { - int i0 = first + 2 * ln + 0; - int i1 = first + 2 * ln + 1; + int i0 = 2 * ln + 0; + int i1 = 2 * ln + 1; res = segmentIsAxisAligned(i0, i1); if (!res) break; } @@ -10702,7 +10811,7 @@ public class PGraphicsOpenGL extends PGraphics { } void tessellateLineStrip() { - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (stroke && 2 <= nInVert) { updateTex(); int lineCount = nInVert - 1; @@ -10726,10 +10835,10 @@ public class PGraphicsOpenGL extends PGraphics { int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast(); firstLineIndexCache = index; - int i0 = in.firstVertex; + int i0 = 0; short[] lastInd = {-1, -1}; for (int ln = 0; ln < lineCount; ln++) { - int i1 = in.firstVertex + ln + 1; + int i1 = ln + 1; if (0 < nBevelTr) { index = addLineSegment3D(i0, i1, index, lastInd, false); } else { @@ -10751,21 +10860,19 @@ public class PGraphicsOpenGL extends PGraphics { tess.polyIndexCache.getLast(); firstLineIndexCache = index; if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index. - int i0 = in.firstVertex; + int i0 = 0; boolean clamp = clampLineStrip2D(lineCount); for (int ln = 0; ln < lineCount; ln++) { - int i1 = in.firstVertex + ln + 1; + int i1 = ln + 1; index = addLineSegment2D(i0, i1, index, false, clamp); i0 = i1; } lastLineIndexCache = lastPolyIndexCache = index; } else { // full stroking algorithm - int first = in.firstVertex; LinePath path = new LinePath(LinePath.WIND_NON_ZERO); - path.moveTo(in.vertices[3 * first + 0], in.vertices[3 * first + 1], - in.strokeColors[first]); + path.moveTo(in.vertices[0], in.vertices[1], in.strokeColors[0]); for (int ln = 0; ln < lineCount; ln++) { - int i1 = first + ln + 1; + int i1 = ln + 1; path.lineTo(in.vertices[3 * i1 + 0], in.vertices[3 * i1 + 1], in.strokeColors[i1]); } @@ -10776,10 +10883,8 @@ public class PGraphicsOpenGL extends PGraphics { boolean clampLineStrip2D(int lineCount) { boolean res = clamp2D(); if (res) { - int i0 = in.firstVertex; for (int ln = 0; ln < lineCount; ln++) { - int i1 = in.firstVertex + ln + 1; - res = segmentIsAxisAligned(i0, i1); + res = segmentIsAxisAligned(0, ln + 1); if (!res) break; } } @@ -10787,7 +10892,7 @@ public class PGraphicsOpenGL extends PGraphics { } void tessellateLineLoop() { - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (stroke && 2 <= nInVert) { updateTex(); int lineCount = nInVert; @@ -10811,11 +10916,11 @@ public class PGraphicsOpenGL extends PGraphics { int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast(); firstLineIndexCache = index; - int i0 = in.firstVertex; + int i0 = 0; short[] lastInd = {-1, -1}; short firstInd = -1; for (int ln = 0; ln < lineCount - 1; ln++) { - int i1 = in.firstVertex + ln + 1; + int i1 = ln + 1; if (0 < nBevelTr) { index = addLineSegment3D(i0, i1, index, lastInd, false); if (ln == 0) firstInd = (short)(lastInd[0] - 2); @@ -10824,10 +10929,9 @@ public class PGraphicsOpenGL extends PGraphics { } i0 = i1; } - index = addLineSegment3D(in.lastVertex, in.firstVertex, index, lastInd, - false); + index = addLineSegment3D(0, in.vertexCount - 1, index, lastInd, false); if (0 < nBevelTr) { - index = addBevel3D(in.firstVertex, index, lastInd, firstInd, false); + index = addBevel3D(0, index, lastInd, firstInd, false); } lastLineIndexCache = index; } @@ -10843,23 +10947,20 @@ public class PGraphicsOpenGL extends PGraphics { tess.polyIndexCache.getLast(); firstLineIndexCache = index; if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index. - int i0 = in.firstVertex; + int i0 = 0; boolean clamp = clampLineLoop2D(lineCount); for (int ln = 0; ln < lineCount - 1; ln++) { - int i1 = in.firstVertex + ln + 1; + int i1 = ln + 1; index = addLineSegment2D(i0, i1, index, false, clamp); i0 = i1; } - index = addLineSegment2D(in.lastVertex, in.firstVertex, index, false, - clamp); + index = addLineSegment2D(0, in.vertexCount - 1, index, false, clamp); lastLineIndexCache = lastPolyIndexCache = index; } else { // full stroking algorithm - int first = in.firstVertex; LinePath path = new LinePath(LinePath.WIND_NON_ZERO); - path.moveTo(in.vertices[3 * first + 0], in.vertices[3 * first + 1], - in.strokeColors[first]); + path.moveTo(in.vertices[0], in.vertices[1], in.strokeColors[0]); for (int ln = 0; ln < lineCount - 1; ln++) { - int i1 = first + ln + 1; + int i1 = ln + 1; path.lineTo(in.vertices[3 * i1 + 0], in.vertices[3 * i1 + 1], in.strokeColors[i1]); } @@ -10871,10 +10972,8 @@ public class PGraphicsOpenGL extends PGraphics { boolean clampLineLoop2D(int lineCount) { boolean res = clamp2D(); if (res) { - int i0 = in.firstVertex; for (int ln = 0; ln < lineCount; ln++) { - int i1 = in.firstVertex + ln + 1; - res = segmentIsAxisAligned(i0, i1); + res = segmentIsAxisAligned(0, ln + 1); if (!res) break; } } @@ -10906,7 +11005,7 @@ public class PGraphicsOpenGL extends PGraphics { firstLineIndexCache = index; short[] lastInd = {-1, -1}; short firstInd = -1; - for (int i = in.firstEdge; i <= in.lastEdge; i++) { + for (int i = 0; i <= in.edgeCount - 1; i++) { int[] edge = in.edges[i]; int i0 = edge[0]; int i1 = edge[1]; @@ -10940,7 +11039,7 @@ public class PGraphicsOpenGL extends PGraphics { firstLineIndexCache = index; if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index. boolean clamp = clampEdges2D(); - for (int i = in.firstEdge; i <= in.lastEdge; i++) { + for (int i = 0; i <= in.edgeCount - 1; i++) { int[] edge = in.edges[i]; if (edge[2] == EDGE_CLOSE) continue; // ignoring edge closures when not doing caps or joins. int i0 = edge[0]; @@ -10950,7 +11049,7 @@ public class PGraphicsOpenGL extends PGraphics { lastLineIndexCache = lastPolyIndexCache = index; } else { // full stroking algorithm LinePath path = new LinePath(LinePath.WIND_NON_ZERO); - for (int i = in.firstEdge; i <= in.lastEdge; i++) { + for (int i = 0; i <= in.edgeCount - 1; i++) { int[] edge = in.edges[i]; int i0 = edge[0]; int i1 = edge[1]; @@ -10991,7 +11090,7 @@ public class PGraphicsOpenGL extends PGraphics { boolean clampEdges2D() { boolean res = clamp2D(); if (res) { - for (int i = in.firstEdge; i <= in.lastEdge; i++) { + for (int i = 0; i <= in.edgeCount - 1; i++) { int[] edge = in.edges[i]; if (edge[2] == EDGE_CLOSE) continue; int i0 = edge[0]; @@ -11236,7 +11335,7 @@ public class PGraphicsOpenGL extends PGraphics { } void unclampLine2D(int tessIdx, float x, float y) { - PMatrix3D mm = modelview; + PMatrix3D mm = pg.modelview; int index = 4 * tessIdx; tess.polyVertices[index++] = x*mm.m00 + y*mm.m01 + mm.m03; tess.polyVertices[index++] = x*mm.m10 + y*mm.m11 + mm.m13; @@ -11303,13 +11402,13 @@ public class PGraphicsOpenGL extends PGraphics { void tessellateTriangles() { beginTex(); - int nTri = (in.lastVertex - in.firstVertex + 1) / 3; + int nTri = in.vertexCount / 3; if (fill && 1 <= nTri) { int nInInd = 3 * nTri; setRawSize(nInInd); int idx = 0; boolean clamp = clampTriangles(); - for (int i = in.firstVertex; i < in.firstVertex + 3 * nTri; i++) { + for (int i = 0; i < 3 * nTri; i++) { rawIndices[idx++] = i; } splitRawIndices(clamp); @@ -11321,7 +11420,7 @@ public class PGraphicsOpenGL extends PGraphics { boolean clampTriangles() { boolean res = clamp2D(); if (res) { - int nTri = (in.lastVertex - in.firstVertex + 1) / 3; + int nTri = in.vertexCount / 3; for (int i = 0; i < nTri; i++) { int i0 = 3 * i + 0; int i1 = 3 * i + 1; @@ -11339,7 +11438,7 @@ public class PGraphicsOpenGL extends PGraphics { void tessellateTriangles(int[] indices) { beginTex(); - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (fill && 3 <= nInVert) { int nInInd = indices.length; setRawSize(nInInd); @@ -11372,14 +11471,14 @@ public class PGraphicsOpenGL extends PGraphics { void tessellateTriangleFan() { beginTex(); - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (fill && 3 <= nInVert) { int nInInd = 3 * (nInVert - 2); setRawSize(nInInd); int idx = 0; boolean clamp = clampTriangleFan(); - for (int i = in.firstVertex + 1; i < in.lastVertex; i++) { - rawIndices[idx++] = in.firstVertex; + for (int i = 1; i < in.vertexCount - 1; i++) { + rawIndices[idx++] = 0; rawIndices[idx++] = i; rawIndices[idx++] = i + 1; } @@ -11392,8 +11491,8 @@ public class PGraphicsOpenGL extends PGraphics { boolean clampTriangleFan() { boolean res = clamp2D(); if (res) { - for (int i = in.firstVertex + 1; i < in.lastVertex; i++) { - int i0 = in.firstVertex; + for (int i = 1; i < in.vertexCount - 1; i++) { + int i0 = 0; int i1 = i; int i2 = i + 1; int count = 0; @@ -11409,13 +11508,13 @@ public class PGraphicsOpenGL extends PGraphics { void tessellateTriangleStrip() { beginTex(); - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (fill && 3 <= nInVert) { int nInInd = 3 * (nInVert - 2); setRawSize(nInInd); int idx = 0; boolean clamp = clampTriangleStrip(); - for (int i = in.firstVertex + 1; i < in.lastVertex; i++) { + for (int i = 1; i < in.vertexCount - 1; i++) { rawIndices[idx++] = i; if (i % 2 == 0) { rawIndices[idx++] = i - 1; @@ -11434,7 +11533,7 @@ public class PGraphicsOpenGL extends PGraphics { boolean clampTriangleStrip() { boolean res = clamp2D(); if (res) { - for (int i = in.firstVertex + 1; i < in.lastVertex; i++) { + for (int i = 1; i < in.vertexCount - 1; i++) { int i0 = i; int i1, i2; if (i % 2 == 0) { @@ -11457,17 +11556,17 @@ public class PGraphicsOpenGL extends PGraphics { void tessellateQuads() { beginTex(); - int quadCount = (in.lastVertex - in.firstVertex + 1) / 4; + int quadCount = in.vertexCount / 4; if (fill && 1 <= quadCount) { int nInInd = 6 * quadCount; setRawSize(nInInd); int idx = 0; boolean clamp = clampQuads(quadCount); for (int qd = 0; qd < quadCount; qd++) { - int i0 = in.firstVertex + 4 * qd + 0; - int i1 = in.firstVertex + 4 * qd + 1; - int i2 = in.firstVertex + 4 * qd + 2; - int i3 = in.firstVertex + 4 * qd + 3; + int i0 = 4 * qd + 0; + int i1 = 4 * qd + 1; + int i2 = 4 * qd + 2; + int i3 = 4 * qd + 3; rawIndices[idx++] = i0; rawIndices[idx++] = i1; @@ -11487,10 +11586,10 @@ public class PGraphicsOpenGL extends PGraphics { boolean res = clamp2D(); if (res) { for (int qd = 0; qd < quadCount; qd++) { - int i0 = in.firstVertex + 4 * qd + 0; - int i1 = in.firstVertex + 4 * qd + 1; - int i2 = in.firstVertex + 4 * qd + 2; - int i3 = in.firstVertex + 4 * qd + 3; + int i0 = 4 * qd + 0; + int i1 = 4 * qd + 1; + int i2 = 4 * qd + 2; + int i3 = 4 * qd + 3; res = segmentIsAxisAligned(i0, i1) && segmentIsAxisAligned(i1, i2) && segmentIsAxisAligned(i2, i3); @@ -11502,17 +11601,17 @@ public class PGraphicsOpenGL extends PGraphics { void tessellateQuadStrip() { beginTex(); - int quadCount = (in.lastVertex - in.firstVertex + 1) / 2 - 1; + int quadCount = in.vertexCount / 2 - 1; if (fill && 1 <= quadCount) { int nInInd = 6 * quadCount; setRawSize(nInInd); int idx = 0; boolean clamp = clampQuadStrip(quadCount); for (int qd = 1; qd < quadCount + 1; qd++) { - int i0 = in.firstVertex + 2 * (qd - 1); - int i1 = in.firstVertex + 2 * (qd - 1) + 1; - int i2 = in.firstVertex + 2 * qd + 1; - int i3 = in.firstVertex + 2 * qd; + int i0 = 2 * (qd - 1); + int i1 = 2 * (qd - 1) + 1; + int i2 = 2 * qd + 1; + int i3 = 2 * qd; rawIndices[idx++] = i0; rawIndices[idx++] = i1; @@ -11532,10 +11631,10 @@ public class PGraphicsOpenGL extends PGraphics { boolean res = clamp2D(); if (res) { for (int qd = 1; qd < quadCount + 1; qd++) { - int i0 = in.firstVertex + 2 * (qd - 1); - int i1 = in.firstVertex + 2 * (qd - 1) + 1; - int i2 = in.firstVertex + 2 * qd + 1; - int i3 = in.firstVertex + 2 * qd; + int i0 = 2 * (qd - 1); + int i1 = 2 * (qd - 1) + 1; + int i2 = 2 * qd + 1; + int i3 = 2 * qd; res = segmentIsAxisAligned(i0, i1) && segmentIsAxisAligned(i1, i2) && segmentIsAxisAligned(i2, i3); @@ -11567,7 +11666,7 @@ public class PGraphicsOpenGL extends PGraphics { // Current index and vertex ranges int inInd0 = 0, inInd1 = 0; - int inMaxVert0 = in.firstVertex, inMaxVert1 = in.firstVertex; + int inMaxVert0 = 0, inMaxVert1 = 0; int inMaxVertRef = inMaxVert0; // Reference vertex where last break split occurred int inMaxVertRel = -1; // Position of vertices from last range relative to @@ -11778,7 +11877,7 @@ public class PGraphicsOpenGL extends PGraphics { void tessellatePolygon(boolean solid, boolean closed, boolean calcNormals) { beginTex(); - int nInVert = in.lastVertex - in.firstVertex + 1; + int nInVert = in.vertexCount; if (fill && 3 <= nInVert) { firstPolyIndexCache = -1; @@ -11799,44 +11898,36 @@ public class PGraphicsOpenGL extends PGraphics { gluTess.beginContour(); // Now, iterate over all input data and send to GLU tessellator.. - for (int i = in.firstVertex; i <= in.lastVertex; i++) { - boolean breakPt = in.breaks[i]; - if (breakPt) { + int vidx = 0; + int cidx = 0; + while (vidx < in.vertexCount) { + boolean brk = in.breaks[vidx]; + + int code = VERTEX; + if (in.codes != null) { + + } + + // in.codes[cidx]; + + if (brk) { gluTess.endContour(); gluTess.beginContour(); } - // Separting colors into individual rgba components for interpolation. - int fa = (in.colors[i] >> 24) & 0xFF; - int fr = (in.colors[i] >> 16) & 0xFF; - int fg = (in.colors[i] >> 8) & 0xFF; - int fb = (in.colors[i] >> 0) & 0xFF; - - int aa = (in.ambient[i] >> 24) & 0xFF; - int ar = (in.ambient[i] >> 16) & 0xFF; - int ag = (in.ambient[i] >> 8) & 0xFF; - int ab = (in.ambient[i] >> 0) & 0xFF; - - int sa = (in.specular[i] >> 24) & 0xFF; - int sr = (in.specular[i] >> 16) & 0xFF; - int sg = (in.specular[i] >> 8) & 0xFF; - int sb = (in.specular[i] >> 0) & 0xFF; - - int ea = (in.emissive[i] >> 24) & 0xFF; - int er = (in.emissive[i] >> 16) & 0xFF; - int eg = (in.emissive[i] >> 8) & 0xFF; - int eb = (in.emissive[i] >> 0) & 0xFF; - - // Vertex data includes coordinates, colors, normals, texture - // coordinates, and material properties. - double[] vertex = new double[] { - in.vertices [3*i + 0], in.vertices [3*i + 1], in.vertices[3*i + 2], - fa, fr, fg, fb, - in.normals [3*i + 0], in.normals [3*i + 1], in.normals [3*i + 2], - in.texcoords[2*i + 0], in.texcoords[2*i + 1], - aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, in.shininess[i]}; - - gluTess.addVertex(vertex); + if (code == BEZIER_VERTEX) { + addBezierVertex(vidx); + vidx += 3; + } else if (code == QUADRATIC_VERTEX) { + addQuadraticVertex(vidx); + vidx += 2; + } else if (code == CURVE_VERTEX) { + addCurveVertex(vidx); + vidx++; + } else { + addVertex(vidx); + vidx++; + } } gluTess.endContour(); @@ -11847,6 +11938,311 @@ public class PGraphicsOpenGL extends PGraphics { tessellateEdges(); } + void addBezierVertex(int i) { + pg.curveVertexCount = 0; + pg.bezierInitCheck(); + pg.bezierVertexCheck(pg.shape, i); + + PMatrix3D draw = pg.bezierDrawMatrix; + + int i1 = i - 1; + float x1 = in.vertices[3*i1 + 0]; + float y1 = in.vertices[3*i1 + 1]; + float z1 = in.vertices[3*i1 + 2]; + + int fa = (in.colors[i] >> 24) & 0xFF; + int fr = (in.colors[i] >> 16) & 0xFF; + int fg = (in.colors[i] >> 8) & 0xFF; + int fb = (in.colors[i] >> 0) & 0xFF; + + int aa = (in.ambient[i] >> 24) & 0xFF; + int ar = (in.ambient[i] >> 16) & 0xFF; + int ag = (in.ambient[i] >> 8) & 0xFF; + int ab = (in.ambient[i] >> 0) & 0xFF; + + int sa = (in.specular[i] >> 24) & 0xFF; + int sr = (in.specular[i] >> 16) & 0xFF; + int sg = (in.specular[i] >> 8) & 0xFF; + int sb = (in.specular[i] >> 0) & 0xFF; + + int ea = (in.emissive[i] >> 24) & 0xFF; + int er = (in.emissive[i] >> 16) & 0xFF; + int eg = (in.emissive[i] >> 8) & 0xFF; + int eb = (in.emissive[i] >> 0) & 0xFF; + + float nx = in.normals[3*i + 0]; + float ny = in.normals[3*i + 1]; + float nz = in.normals[3*i + 2]; + float u = in.texcoords[2*i + 0]; + float v = in.texcoords[2*i + 1]; + float sh = in.shininess[i]; + + float x2 = in.vertices[3*i + 0]; + float y2 = in.vertices[3*i + 1]; + float z2 = in.vertices[3*i + 2]; + float x3 = in.vertices[3*(i+1) + 0]; + float y3 = in.vertices[3*(i+1) + 1]; + float z3 = in.vertices[3*(i+1) + 2]; + float x4 = in.vertices[3*(i+2) + 0]; + float y4 = in.vertices[3*(i+2) + 1]; + float z4 = in.vertices[3*(i+2) + 2]; + + float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4; + float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4; + float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4; + + float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4; + float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4; + float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4; + + float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4; + float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4; + float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4; + + for (int j = 0; j < pg.bezierDetail; j++) { + x1 += xplot1; xplot1 += xplot2; xplot2 += xplot3; + y1 += yplot1; yplot1 += yplot2; yplot2 += yplot3; + z1 += zplot1; zplot1 += zplot2; zplot2 += zplot3; + double[] vertex = new double[] { + x1, y1, z1, + fa, fr, fg, fb, + nx, ny, nz, + u, v, + aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, sh}; + gluTess.addVertex(vertex); + } + } + + void addQuadraticVertex(int i) { + pg.curveVertexCount = 0; + pg.bezierInitCheck(); + pg.bezierVertexCheck(pg.shape, i); + + PMatrix3D draw = pg.bezierDrawMatrix; + + int i1 = i - 1; + float x1 = in.vertices[3*i1 + 0]; + float y1 = in.vertices[3*i1 + 1]; + float z1 = in.vertices[3*i1 + 2]; + + int fa = (in.colors[i] >> 24) & 0xFF; + int fr = (in.colors[i] >> 16) & 0xFF; + int fg = (in.colors[i] >> 8) & 0xFF; + int fb = (in.colors[i] >> 0) & 0xFF; + + int aa = (in.ambient[i] >> 24) & 0xFF; + int ar = (in.ambient[i] >> 16) & 0xFF; + int ag = (in.ambient[i] >> 8) & 0xFF; + int ab = (in.ambient[i] >> 0) & 0xFF; + + int sa = (in.specular[i] >> 24) & 0xFF; + int sr = (in.specular[i] >> 16) & 0xFF; + int sg = (in.specular[i] >> 8) & 0xFF; + int sb = (in.specular[i] >> 0) & 0xFF; + + int ea = (in.emissive[i] >> 24) & 0xFF; + int er = (in.emissive[i] >> 16) & 0xFF; + int eg = (in.emissive[i] >> 8) & 0xFF; + int eb = (in.emissive[i] >> 0) & 0xFF; + + float nx = in.normals[3*i + 0]; + float ny = in.normals[3*i + 1]; + float nz = in.normals[3*i + 2]; + float u = in.texcoords[2*i + 0]; + float v = in.texcoords[2*i + 1]; + float sh = in.shininess[i]; + + float cx = in.vertices[3*i + 0]; + float cy = in.vertices[3*i + 1]; + float cz = in.vertices[3*i + 2]; + float x = in.vertices[3*(i+1) + 0]; + float y = in.vertices[3*(i+1) + 1]; + float z = in.vertices[3*(i+1) + 2]; + + float x2 = x1 + ((cx-x1)*2/3.0f); + float y2 = y1 + ((cy-y1)*2/3.0f); + float z2 = z1 + ((cz-z1)*2/3.0f); + float x3 = x + ((cx-x)*2/3.0f); + float y3 = y + ((cy-y)*2/3.0f); + float z3 = z + ((cz-z)*2/3.0f); + float x4 = x; + float y4 = y; + float z4 = z; + + float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4; + float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4; + float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4; + + float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4; + float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4; + float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4; + + float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4; + float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4; + float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4; + + for (int j = 0; j < pg.bezierDetail; j++) { + x1 += xplot1; xplot1 += xplot2; xplot2 += xplot3; + y1 += yplot1; yplot1 += yplot2; yplot2 += yplot3; + z1 += zplot1; zplot1 += zplot2; zplot2 += zplot3; + double[] vertex = new double[] { + x1, y1, z1, + fa, fr, fg, fb, + nx, ny, nz, + u, v, + aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, sh}; + + gluTess.addVertex(vertex); + } + +/* + float x1 = getLastVertexX(); + float y1 = getLastVertexY(); + float z1 = getLastVertexZ(); + addBezierVertex( + x1 + ((cx-x1)*2/3.0f), y1 + ((cy-y1)*2/3.0f), z1 + ((cz-z1)*2/3.0f), + x3 + ((cx-x3)*2/3.0f), y3 + ((cy-y3)*2/3.0f), z3 + ((cz-z3)*2/3.0f), + x3, y3, z3, + fill, stroke, detail, code, shape); + */ + } + + void addCurveVertex(int i) { + pg.curveVertexCheck(pg.shape); + + float[] vertex = pg.curveVertices[pg.curveVertexCount]; + vertex[X] = in.vertices[3*i + 0]; + vertex[Y] = in.vertices[3*i + 1]; + vertex[Z] = in.vertices[3*i + 2]; + + pg.curveVertexCount++; + + // draw a segment if there are enough points + if (pg.curveVertexCount > 3) { + float[] v1 = pg.curveVertices[pg.curveVertexCount - 4]; + float[] v2 = pg.curveVertices[pg.curveVertexCount - 3]; + float[] v3 = pg.curveVertices[pg.curveVertexCount - 2]; + float[] v4 = pg.curveVertices[pg.curveVertexCount - 1]; + addCurveVertexSegment(i, v1[X], v1[Y], v1[Z], + v2[X], v2[Y], v2[Z], + v3[X], v3[Y], v3[Z], + v4[X], v4[Y], v4[Z]); + } + } + + void addCurveVertexSegment(int i, float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + int fa = (in.colors[i] >> 24) & 0xFF; + int fr = (in.colors[i] >> 16) & 0xFF; + int fg = (in.colors[i] >> 8) & 0xFF; + int fb = (in.colors[i] >> 0) & 0xFF; + + int aa = (in.ambient[i] >> 24) & 0xFF; + int ar = (in.ambient[i] >> 16) & 0xFF; + int ag = (in.ambient[i] >> 8) & 0xFF; + int ab = (in.ambient[i] >> 0) & 0xFF; + + int sa = (in.specular[i] >> 24) & 0xFF; + int sr = (in.specular[i] >> 16) & 0xFF; + int sg = (in.specular[i] >> 8) & 0xFF; + int sb = (in.specular[i] >> 0) & 0xFF; + + int ea = (in.emissive[i] >> 24) & 0xFF; + int er = (in.emissive[i] >> 16) & 0xFF; + int eg = (in.emissive[i] >> 8) & 0xFF; + int eb = (in.emissive[i] >> 0) & 0xFF; + + float nx = in.normals[3*i + 0]; + float ny = in.normals[3*i + 1]; + float nz = in.normals[3*i + 2]; + float u = in.texcoords[2*i + 0]; + float v = in.texcoords[2*i + 1]; + float sh = in.shininess[i]; + + float x0 = x2; + float y0 = y2; + float z0 = z2; + + PMatrix3D draw = pg.curveDrawMatrix; + + float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4; + float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4; + float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4; + + float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4; + float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4; + float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4; + + float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4; + float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4; + float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4; + + // addVertex() will reset curveVertexCount, so save it +// int savedCount = pg.curveVertexCount; + + //addVertex(x0, y0, z0, code == BREAK ? BREAK : VERTEX); + double[] vertex0 = new double[] { + x0, y0, z0, + fa, fr, fg, fb, + nx, ny, nz, + u, v, + aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, sh}; + gluTess.addVertex(vertex0); + + for (int j = 0; j < pg.curveDetail; j++) { + x0 += xplot1; xplot1 += xplot2; xplot2 += xplot3; + y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3; + z0 += zplot1; zplot1 += zplot2; zplot2 += zplot3; + double[] vertex1 = new double[] { + x0, y0, z0, + fa, fr, fg, fb, + nx, ny, nz, + u, v, + aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, sh}; + gluTess.addVertex(vertex1); + } + +// pg.curveVertexCount = savedCount; + } + + void addVertex(int i) { + pg.curveVertexCount = 0; + + // Separting colors into individual rgba components for interpolation. + int fa = (in.colors[i] >> 24) & 0xFF; + int fr = (in.colors[i] >> 16) & 0xFF; + int fg = (in.colors[i] >> 8) & 0xFF; + int fb = (in.colors[i] >> 0) & 0xFF; + + int aa = (in.ambient[i] >> 24) & 0xFF; + int ar = (in.ambient[i] >> 16) & 0xFF; + int ag = (in.ambient[i] >> 8) & 0xFF; + int ab = (in.ambient[i] >> 0) & 0xFF; + + int sa = (in.specular[i] >> 24) & 0xFF; + int sr = (in.specular[i] >> 16) & 0xFF; + int sg = (in.specular[i] >> 8) & 0xFF; + int sb = (in.specular[i] >> 0) & 0xFF; + + int ea = (in.emissive[i] >> 24) & 0xFF; + int er = (in.emissive[i] >> 16) & 0xFF; + int eg = (in.emissive[i] >> 8) & 0xFF; + int eb = (in.emissive[i] >> 0) & 0xFF; + + // Vertex data includes coordinates, colors, normals, texture + // coordinates, and material properties. + double[] vertex = new double[] { + in.vertices [3*i + 0], in.vertices [3*i + 1], in.vertices[3*i + 2], + fa, fr, fg, fb, + in.normals [3*i + 0], in.normals [3*i + 1], in.normals [3*i + 2], + in.texcoords[2*i + 0], in.texcoords[2*i + 1], + aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, in.shininess[i]}; + + gluTess.addVertex(vertex); + } + boolean clampPolygon() { return false; } diff --git a/core/src/processing/opengl/PShader.java b/core/src/processing/opengl/PShader.java index 0bc608368..220f93352 100644 --- a/core/src/processing/opengl/PShader.java +++ b/core/src/processing/opengl/PShader.java @@ -51,13 +51,12 @@ public class PShader { protected PApplet parent; // The main renderer associated to the parent PApplet. - protected PGraphicsOpenGL pgMain; + //protected PGraphicsOpenGL pgMain; // We need a reference to the renderer since a shader might // be called by different renderers within a single application // (the one corresponding to the main surface, or other offscreen // renderers). - protected PGraphicsOpenGL pgCurrent; - + protected PGraphicsOpenGL pg; protected PGL pgl; protected int context; // The context that created this shader. @@ -87,7 +86,7 @@ public class PShader { public PShader() { parent = null; - pgMain = null; +// pgMain = null; pgl = null; context = -1; @@ -110,7 +109,7 @@ public class PShader { public PShader(PApplet parent) { this(); this.parent = parent; - pgMain = (PGraphicsOpenGL) parent.g; +// pgMain = (PGraphicsOpenGL) parent.g; pgl = PGraphicsOpenGL.pgl; context = pgl.createEmptyContext(); } @@ -126,7 +125,7 @@ public class PShader { */ public PShader(PApplet parent, String vertFilename, String fragFilename) { this.parent = parent; - pgMain = (PGraphicsOpenGL) parent.g; +// pgMain = (PGraphicsOpenGL) parent.g; pgl = PGraphicsOpenGL.pgl; this.vertexURL = null; @@ -149,7 +148,7 @@ public class PShader { */ public PShader(PApplet parent, URL vertURL, URL fragURL) { this.parent = parent; - pgMain = (PGraphicsOpenGL) parent.g; +// pgMain = (PGraphicsOpenGL) parent.g; pgl = PGraphicsOpenGL.pgl; this.vertexURL = vertURL; @@ -623,7 +622,7 @@ public class PShader { pgl.uniformMatrix4fv(loc, 1, false, floatBuffer); } else if (val.type == UniformValue.SAMPLER2D) { PImage img = (PImage)val.value; - Texture tex = pgMain.getTexture(img); + Texture tex = PGraphicsOpenGL.pgPrimary.getTexture(img); if (textures == null) textures = new HashMap(); textures.put(loc, tex); @@ -869,7 +868,7 @@ public class PShader { protected void setRenderer(PGraphicsOpenGL pg) { - pgCurrent = pg; + this.pg = pg; } protected void loadAttributes() { } diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index bd33f666f..5d4ce029e 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -186,9 +186,13 @@ public class PShapeOpenGL extends PShape { // Bezier and Catmull-Rom curves - protected int bezierDetail = 20; - protected int curveDetail = 20; - protected float curveTightness = 0; + protected int bezierDetail; + protected int curveDetail; + protected float curveTightness; + + protected int savedBezierDetail; + protected int savedCurveDetail; + protected float savedCurveTightness; // ........................................................ @@ -290,7 +294,7 @@ public class PShapeOpenGL extends PShape { public PShapeOpenGL(PApplet parent, int family) { - pg = (PGraphicsOpenGL)parent.g; + pg = PGraphicsOpenGL.pgCurrent; pgl = PGraphicsOpenGL.pgl; context = pgl.createEmptyContext(); @@ -321,7 +325,7 @@ public class PShapeOpenGL extends PShape { this.tessellated = false; if (family == GEOMETRY || family == PRIMITIVE || family == PATH) { - inGeo = pg.newInGeometry(PGraphicsOpenGL.RETAINED); + inGeo = PGraphicsOpenGL.newInGeometry(pg, PGraphicsOpenGL.RETAINED); } // Style parameters are retrieved from the current values in the renderer. @@ -356,6 +360,10 @@ public class PShapeOpenGL extends PShape { sphereDetailU = pg.sphereDetailU; sphereDetailV = pg.sphereDetailV; + bezierDetail = pg.bezierDetail; + curveDetail = pg.curveDetail; + curveTightness = pg.curveTightness; + // The rect and ellipse modes are set to CORNER since it is the expected // mode for svg shapes. rectMode = CORNER; @@ -1061,24 +1069,23 @@ public class PShapeOpenGL extends PShape { } inGeo.addVertex(x, y, z, - fcolor, - normalX, normalY, normalZ, - u, v, - scolor, sweight, - ambientColor, specularColor, emissiveColor, shininess, - vertexCode()); + fcolor, + normalX, normalY, normalZ, + u, v, + scolor, sweight, + ambientColor, specularColor, emissiveColor, shininess, + VERTEX, vertexBreak()); markForTessellation(); } - protected int vertexCode() { - int code = VERTEX; + protected boolean vertexBreak() { if (breakShape) { - code = BREAK; breakShape = false; + return true; } - return code; + return false; } @@ -1382,7 +1389,10 @@ public class PShapeOpenGL extends PShape { @Override public void bezierDetail(int detail) { bezierDetail = detail; - pg.bezierDetail(detail); + if (0 < inGeo.codeCount) { + markForTessellation(); + } + //pg.bezierDetail(detail); // setting the detail in the renderer, WTF?? } @@ -1414,8 +1424,15 @@ public class PShapeOpenGL extends PShape { inGeo.setNormal(normalX, normalY, normalZ); inGeo.addBezierVertex(x2, y2, z2, x3, y3, z3, - x4, y4, z4, - fill, stroke, bezierDetail, vertexCode(), kind); + x4, y4, z4, vertexBreak()); + +// inGeo.addVertex(x2, y2, z2, BEZIER_VERTEX, vertexBreak()); +// inGeo.addVertex(x3, y3, z3, BEZIER_VERTEX, false); +// inGeo.addVertex(x4, y4, z4, BEZIER_VERTEX, false); +//// inGeo.addBezierVertex(x2, y2, z2, +// x3, y3, z3, +// x4, y4, z4, +// fill, stroke, bezierDetail, vertexCode(), kind); } @@ -1441,8 +1458,12 @@ public class PShapeOpenGL extends PShape { ambientColor, specularColor, emissiveColor, shininess); inGeo.setNormal(normalX, normalY, normalZ); inGeo.addQuadraticVertex(cx, cy, cz, - x3, y3, z3, - fill, stroke, bezierDetail, vertexCode(), kind); + x3, y3, z3, vertexBreak()); +// inGeo.addVertex(cx, cy, cz, QUADRATIC_VERTEX, vertexBreak()); +// inGeo.addVertex(x3, y3, z3, QUADRATIC_VERTEX, false); +// inGeo.addQuadraticVertex(cx, cy, cz, +// x3, y3, z3, +// fill, stroke, bezierDetail, vertexCode(), kind); } @@ -1456,14 +1477,20 @@ public class PShapeOpenGL extends PShape { @Override public void curveDetail(int detail) { curveDetail = detail; - pg.curveDetail(detail); +// pg.curveDetail(detail); + if (0 < inGeo.codeCount) { + markForTessellation(); + } } @Override public void curveTightness(float tightness) { curveTightness = tightness; - pg.curveTightness(tightness); +// pg.curveTightness(tightness); + if (0 < inGeo.codeCount) { + markForTessellation(); + } } @@ -1483,8 +1510,10 @@ public class PShapeOpenGL extends PShape { inGeo.setMaterial(fillColor, strokeColor, strokeWeight, ambientColor, specularColor, emissiveColor, shininess); inGeo.setNormal(normalX, normalY, normalZ); - inGeo.addCurveVertex(x, y, z, - fill, stroke, curveDetail, vertexCode(), kind); + inGeo.addCurveVertex(x, y, z, vertexBreak()); +// inGeo.addVertex(x, y, z, CURVE_VERTEX, vertexBreak()); +// inGeo.addCurveVertex(x, y, z, +// fill, stroke, curveDetail, vertexCode(), kind); } @@ -1856,7 +1885,7 @@ public class PShapeOpenGL extends PShape { } else if (this.stroke != stroke) { if (this.stroke) { // Disabling stroke on a shape previously with - // stroke needs a re-tesellation in order to remove + // stroke needs a re-tessellation in order to remove // the additional geometry of lines and/or points. markForTessellation(); stroke = false; @@ -1977,7 +2006,7 @@ public class PShapeOpenGL extends PShape { root.setModifiedLineAttributes(firstLineVertex, lastLineVertex); } else if (is2D()) { // Changing the stroke weight on a 2D shape needs a - // re-tesellation in order to replace the old line + // re-tessellation in order to replace the old line // geometry. markForTessellation(); } @@ -1991,7 +2020,7 @@ public class PShapeOpenGL extends PShape { root.setModifiedPointAttributes(firstPointVertex, lastPointVertex); } else if (is2D()) { // Changing the stroke weight on a 2D shape needs a - // re-tesellation in order to replace the old point + // re-tessellation in order to replace the old point // geometry. markForTessellation(); } @@ -2027,7 +2056,7 @@ public class PShapeOpenGL extends PShape { } else { if (is2D() && strokeJoin != join) { // Changing the stroke join on a 2D shape needs a - // re-tesellation in order to replace the old join + // re-tessellation in order to replace the old join // geometry. markForTessellation(); } @@ -2051,7 +2080,7 @@ public class PShapeOpenGL extends PShape { } else { if (is2D() && strokeCap != cap) { // Changing the stroke cap on a 2D shape needs a - // re-tesellation in order to replace the old cap + // re-tessellation in order to replace the old cap // geometry. markForTessellation(); } @@ -2311,6 +2340,44 @@ public class PShapeOpenGL extends PShape { markForTessellation(); } + /////////////////////////////////////////////////////////// + + // + + // Vertex codes + + @Override + public int[] getVertexCodes() { + if (family == GROUP) return null; + else { + if (inGeo.codes == null) { + return null; + } + if (inGeo.codes.length != inGeo.codeCount) { + inGeo.codes = PApplet.subset(inGeo.codes, 0, inGeo.codeCount); + } + return inGeo.codes; + } + } + + + @Override + public int getVertexCodeCount() { + if (family == GROUP) return 0; + else { + return inGeo.codeCount; + } + } + + + /** + * One of VERTEX, BEZIER_VERTEX, CURVE_VERTEX, or BREAK. + */ + @Override + public int getVertexCode(int index) { + return inGeo.codes[index]; + } + /////////////////////////////////////////////////////////// @@ -2318,6 +2385,7 @@ public class PShapeOpenGL extends PShape { // Tessellated geometry getter. + @Override public PShape getTessellation() { updateTessellation(); @@ -2413,6 +2481,34 @@ public class PShapeOpenGL extends PShape { } + /////////////////////////////////////////////////////////// + + // + + // Geometry utils + + // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + @Override + public boolean contains(float x, float y) { + if (family == PATH) { + boolean c = false; + for (int i = 0, j = inGeo.vertexCount-1; i < inGeo.vertexCount; j = i++) { + if (((inGeo.vertices[3 * i + 1] > y) != (inGeo.vertices[3 * j + 1] > y)) && + (x < + (inGeo.vertices[3 * j]-inGeo.vertices[3 * i]) * + (y-inGeo.vertices[3 * i + 1]) / + (inGeo.vertices[3 * j + 1]-inGeo.vertices[3 * i + 1]) + + inGeo.vertices[3 * i])) { + c = !c; + } + } + return c; + } else { + throw new IllegalArgumentException("The contains() method is only implemented for paths."); + } + } + + /////////////////////////////////////////////////////////// // @@ -2492,7 +2588,7 @@ public class PShapeOpenGL extends PShape { protected void tessellate() { if (root == this && parent == null) { if (tessGeo == null) { - tessGeo = pg.newTessGeometry(PGraphicsOpenGL.RETAINED); + tessGeo = PGraphicsOpenGL.newTessGeometry(pg, PGraphicsOpenGL.RETAINED); } tessGeo.clear(); @@ -2532,12 +2628,13 @@ public class PShapeOpenGL extends PShape { tessellator.setInGeometry(inGeo); tessellator.setTessGeometry(tessGeo); tessellator.setFill(fill || image != null); + tessellator.setTexCache(null, null, null); tessellator.setStroke(stroke); tessellator.setStrokeColor(strokeColor); tessellator.setStrokeWeight(strokeWeight); tessellator.setStrokeCap(strokeCap); tessellator.setStrokeJoin(strokeJoin); - tessellator.setTexCache(null, null, null); + tessellator.setRenderer(pg); tessellator.setTransform(matrix); tessellator.set3D(is3D()); @@ -2571,9 +2668,16 @@ public class PShapeOpenGL extends PShape { if (normalMode == NORMAL_MODE_AUTO) inGeo.calcQuadStripNormals(); tessellator.tessellateQuadStrip(); } else if (kind == POLYGON) { + boolean bez = inGeo.hasBezierVertex(); + boolean quad = inGeo.hasQuadraticVertex(); + boolean curv = inGeo.hasCurveVertex(); + if (bez || quad) saveBezierVertexSettings(); + if (curv) saveCurveVertexSettings(); if (stroke) inGeo.addPolygonEdges(close); tessellator.tessellatePolygon(solid, close, normalMode == NORMAL_MODE_AUTO); + if (bez ||quad) restoreBezierVertexSettings(); + if (curv) restoreCurveVertexSettings(); } } else if (family == PRIMITIVE) { // The input geometry needs to be cleared because the geometry @@ -2720,7 +2824,7 @@ public class PShapeOpenGL extends PShape { x2, y2, 0, x3, y3, 0, x4, y4, 0, - fill, stroke); + stroke); tessellator.tessellateQuads(); } @@ -2797,11 +2901,12 @@ public class PShapeOpenGL extends PShape { ambientColor, specularColor, emissiveColor, shininess); inGeo.setNormal(normalX, normalY, normalZ); if (rounded) { - inGeo.addRect(a, b, c, d, tl, tr, br, bl, - fill, stroke, bezierDetail); + saveBezierVertexSettings(); + inGeo.addRect(a, b, c, d, tl, tr, br, bl, stroke); tessellator.tessellatePolygon(false, true, true); + restoreBezierVertexSettings(); } else { - inGeo.addRect(a, b, c, d, fill, stroke); + inGeo.addRect(a, b, c, d, stroke); tessellator.tessellateQuads(); } } @@ -2951,10 +3056,23 @@ public class PShapeOpenGL extends PShape { } } + if (nu < 3 || nv < 2) { + nu = nv = 30; + } + int savedDetailU = pg.sphereDetailU; + int savedDetailV = pg.sphereDetailV; + if (pg.sphereDetailU != nu || pg.sphereDetailV != nv) { + pg.sphereDetail(nu, nv); + } + inGeo.setMaterial(fillColor, strokeColor, strokeWeight, ambientColor, specularColor, emissiveColor, shininess); int[] indices = inGeo.addSphere(r, nu, nv, fill, stroke); tessellator.tessellateTriangles(indices); + + if (savedDetailU != nu || savedDetailV != nv) { + pg.sphereDetail(savedDetailU, savedDetailV); + } } @@ -2965,18 +3083,19 @@ public class PShapeOpenGL extends PShape { ambientColor, specularColor, emissiveColor, shininess); if (vertexCodeCount == 0) { // each point is a simple vertex - if (vertices[0].length == 2) { // tesellating 2D vertices + if (vertices[0].length == 2) { // tessellating 2D vertices for (int i = 0; i < vertexCount; i++) { - inGeo.addVertex(vertices[i][X], vertices[i][Y], VERTEX); + inGeo.addVertex(vertices[i][X], vertices[i][Y], VERTEX, false); } } else { // drawing 3D vertices for (int i = 0; i < vertexCount; i++) { - inGeo.addVertex(vertices[i][X], vertices[i][Y], vertices[i][Z], VERTEX); + inGeo.addVertex(vertices[i][X], vertices[i][Y], vertices[i][Z], + VERTEX, false); } } } else { // coded set of vertices int idx = 0; - int code = BREAK; + boolean brk = true; if (vertices[0].length == 2) { // tessellating a 2D path @@ -2984,16 +3103,16 @@ public class PShapeOpenGL extends PShape { switch (vertexCodes[j]) { case VERTEX: - inGeo.addVertex(vertices[idx][X], vertices[idx][Y], code); - code = VERTEX; + inGeo.addVertex(vertices[idx][X], vertices[idx][Y], VERTEX, brk); + brk = false; idx++; break; case QUADRATIC_VERTEX: inGeo.addQuadraticVertex(vertices[idx+0][X], vertices[idx+0][Y], 0, vertices[idx+1][X], vertices[idx+1][Y], 0, - fill, stroke, bezierDetail, code); - code = VERTEX; + brk); + brk = false; idx += 2; break; @@ -3001,20 +3120,19 @@ public class PShapeOpenGL extends PShape { inGeo.addBezierVertex(vertices[idx+0][X], vertices[idx+0][Y], 0, vertices[idx+1][X], vertices[idx+1][Y], 0, vertices[idx+2][X], vertices[idx+2][Y], 0, - fill, stroke, bezierDetail, code); - code = VERTEX; + brk); + brk = false; idx += 3; break; case CURVE_VERTEX: - inGeo.addCurveVertex(vertices[idx][X], vertices[idx][Y], 0, - fill, stroke, curveDetail, code); - code = VERTEX; + inGeo.addCurveVertex(vertices[idx][X], vertices[idx][Y], 0, brk); + brk = false; idx++; break; case BREAK: - code = BREAK; + brk = true; } } } else { // tessellating a 3D path @@ -3023,8 +3141,8 @@ public class PShapeOpenGL extends PShape { case VERTEX: inGeo.addVertex(vertices[idx][X], vertices[idx][Y], - vertices[idx][Z], code); - code = VERTEX; + vertices[idx][Z], brk); + brk = false; idx++; break; @@ -3035,12 +3153,11 @@ public class PShapeOpenGL extends PShape { vertices[idx+1][X], vertices[idx+1][Y], vertices[idx+0][Z], - fill, stroke, bezierDetail, code); - code = VERTEX; + brk); + brk = false; idx += 2; break; - case BEZIER_VERTEX: inGeo.addBezierVertex(vertices[idx+0][X], vertices[idx+0][Y], @@ -3051,8 +3168,8 @@ public class PShapeOpenGL extends PShape { vertices[idx+2][X], vertices[idx+2][Y], vertices[idx+2][Z], - fill, stroke, bezierDetail, code); - code = VERTEX; + brk); + brk = false; idx += 3; break; @@ -3060,22 +3177,61 @@ public class PShapeOpenGL extends PShape { inGeo.addCurveVertex(vertices[idx][X], vertices[idx][Y], vertices[idx][Z], - fill, stroke, curveDetail, code); - code = VERTEX; + brk); + brk = false; idx++; break; case BREAK: - code = BREAK; + brk = true; } } } } + boolean bez = inGeo.hasBezierVertex(); + boolean quad = inGeo.hasQuadraticVertex(); + boolean curv = inGeo.hasCurveVertex(); + if (bez || quad) saveBezierVertexSettings(); + if (curv) saveCurveVertexSettings(); if (stroke) inGeo.addPolygonEdges(close); tessellator.tessellatePolygon(false, close, true); + if (bez || quad) restoreBezierVertexSettings(); + if (curv) restoreCurveVertexSettings(); } + protected void saveBezierVertexSettings() { + savedBezierDetail = pg.bezierDetail; + if (pg.bezierDetail != bezierDetail) { + pg.bezierDetail(bezierDetail); + } + } + + protected void restoreBezierVertexSettings() { + if (savedBezierDetail != bezierDetail) { + pg.bezierDetail(savedBezierDetail); + } + } + + protected void saveCurveVertexSettings() { + savedCurveDetail = pg.curveDetail; + savedCurveTightness = pg.curveTightness; + if (pg.curveDetail != curveDetail) { + pg.curveDetail(curveDetail); + } + if (pg.curveTightness != curveTightness) { + pg.curveTightness(curveTightness); + } + } + + protected void restoreCurveVertexSettings() { + if (savedCurveDetail != curveDetail) { + pg.curveDetail(savedCurveDetail); + } + if (savedCurveTightness != curveTightness) { + pg.curveTightness(savedCurveTightness); + } + } ///////////////////////////////////////////////////////////