mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
reworking logic for 2D clamping
This commit is contained in:
@@ -523,10 +523,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected IntBuffer intBuffer;
|
||||
protected FloatBuffer floatBuffer;
|
||||
|
||||
|
||||
/** Flag used to disable coord clamping in 2D when strokes have fractional weight */
|
||||
protected boolean clampingEnabled = false;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// INIT/ALLOCATE/FINISH
|
||||
@@ -2193,6 +2189,8 @@ 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();
|
||||
@@ -9909,29 +9907,32 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int rgba,
|
||||
float nx, float ny, float nz,
|
||||
float u, float v,
|
||||
int am, int sp, int em, float shine) {
|
||||
int am, int sp, int em, float shine,
|
||||
boolean clamp) {
|
||||
polyVertexCheck();
|
||||
int tessIdx = polyVertexCount - 1;
|
||||
setPolyVertex(tessIdx, x, y, z,
|
||||
rgba,
|
||||
nx, ny, nz,
|
||||
u, v,
|
||||
am, sp, em, shine);
|
||||
am, sp, em, shine, clamp);
|
||||
}
|
||||
|
||||
void setPolyVertex(int tessIdx, float x, float y, float z, int rgba) {
|
||||
void setPolyVertex(int tessIdx, float x, float y, float z, int rgba,
|
||||
boolean clamp) {
|
||||
setPolyVertex(tessIdx, x, y, z,
|
||||
rgba,
|
||||
0, 0, 1,
|
||||
0, 0,
|
||||
0, 0, 0, 0);
|
||||
0, 0, 0, 0, clamp);
|
||||
}
|
||||
|
||||
void setPolyVertex(int tessIdx, float x, float y, float z,
|
||||
int rgba,
|
||||
float nx, float ny, float nz,
|
||||
float u, float v,
|
||||
int am, int sp, int em, float shine) {
|
||||
int am, int sp, int em, float shine,
|
||||
boolean clamp) {
|
||||
int index;
|
||||
|
||||
if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL) {
|
||||
@@ -9939,20 +9940,18 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
PMatrix3D nm = modelviewInv;
|
||||
|
||||
index = 4 * tessIdx;
|
||||
if (is2D() && clampingEnabled) {
|
||||
if (is2D() && clamp) {
|
||||
// ceil emulates the behavior of JAVA2D
|
||||
polyVertices[index++] =
|
||||
PApplet.ceil(x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03);
|
||||
polyVertices[index++] =
|
||||
PApplet.ceil(x*mm.m10 + y*mm.m11 + z*mm.m12 + mm.m13);
|
||||
polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23;
|
||||
polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33;
|
||||
} else {
|
||||
polyVertices[index++] = x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03;
|
||||
polyVertices[index++] = x*mm.m10 + y*mm.m11 + z*mm.m12 + mm.m13;
|
||||
polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23;
|
||||
polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33;
|
||||
}
|
||||
polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23;
|
||||
polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33;
|
||||
|
||||
index = 3 * tessIdx;
|
||||
polyNormals[index++] = nx*nm.m00 + ny*nm.m10 + nz*nm.m20;
|
||||
@@ -9983,15 +9982,15 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
polyShininess[tessIdx] = shine;
|
||||
}
|
||||
|
||||
void addPolyVertices(InGeometry in) {
|
||||
addPolyVertices(in, in.firstVertex, in.lastVertex);
|
||||
void addPolyVertices(InGeometry in, boolean clamp) {
|
||||
addPolyVertices(in, in.firstVertex, in.lastVertex, clamp);
|
||||
}
|
||||
|
||||
void addPolyVertex(InGeometry in, int i) {
|
||||
addPolyVertices(in, i, i);
|
||||
void addPolyVertex(InGeometry in, int i, boolean clamp) {
|
||||
addPolyVertices(in, i, i, clamp);
|
||||
}
|
||||
|
||||
void addPolyVertices(InGeometry in, int i0, int i1) {
|
||||
void addPolyVertices(InGeometry in, int i0, int i1, boolean clamp) {
|
||||
int index;
|
||||
int nvert = i1 - i0 + 1;
|
||||
|
||||
@@ -10016,19 +10015,18 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
float nz = in.normals[index ];
|
||||
|
||||
index = 4 * tessIdx;
|
||||
if (is2D() && clampingEnabled) {
|
||||
if (is2D() && clamp) {
|
||||
// ceil emulates the behavior of JAVA2D
|
||||
polyVertices[index++] =
|
||||
PApplet.ceil(x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03);
|
||||
polyVertices[index++] =
|
||||
PApplet.ceil(x*mm.m10 + y*mm.m11 + z*mm.m12 + mm.m13);
|
||||
polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23;
|
||||
polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33;
|
||||
} else {
|
||||
polyVertices[index++] = x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03;
|
||||
polyVertices[index++] = x*mm.m10 + y*mm.m11 + z*mm.m12 + mm.m13;
|
||||
polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23;
|
||||
polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33;
|
||||
}
|
||||
polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23;
|
||||
polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33;
|
||||
|
||||
index = 3 * tessIdx;
|
||||
polyNormals[index++] = nx*nm.m00 + ny*nm.m10 + nz*nm.m20;
|
||||
@@ -10528,13 +10526,13 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
float val = 0;
|
||||
float inc = (float) SINCOS_LENGTH / perim;
|
||||
tess.setPolyVertex(vertIdx, x0, y0, 0, rgba);
|
||||
tess.setPolyVertex(vertIdx, x0, y0, 0, rgba, false);
|
||||
vertIdx++;
|
||||
for (int k = 0; k < perim; k++) {
|
||||
tess.setPolyVertex(vertIdx,
|
||||
x0 + 0.5f * cosLUT[(int) val] * strokeWeight,
|
||||
y0 + 0.5f * sinLUT[(int) val] * strokeWeight,
|
||||
0, rgba);
|
||||
0, rgba, false);
|
||||
vertIdx++;
|
||||
val = (val + inc) % SINCOS_LENGTH;
|
||||
}
|
||||
@@ -10636,6 +10634,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
void tessellateSquarePoints2D(int nvertTot, int nindTot) {
|
||||
tess.polyVertexCheck(nvertTot);
|
||||
tess.polyIndexCheck(nindTot);
|
||||
boolean clamp = clampSquarePoints2D();
|
||||
int vertIdx = tess.firstPolyVertex;
|
||||
int indIdx = tess.firstPolyIndex;
|
||||
IndexCache cache = tess.polyIndexCache;
|
||||
@@ -10654,13 +10653,13 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
float y0 = in.vertices[3 * i + 1];
|
||||
int rgba = in.strokeColors[i];
|
||||
|
||||
tess.setPolyVertex(vertIdx, x0, y0, 0, rgba);
|
||||
tess.setPolyVertex(vertIdx, x0, y0, 0, rgba, clamp);
|
||||
vertIdx++;
|
||||
for (int k = 0; k < nvert - 1; k++) {
|
||||
tess.setPolyVertex(vertIdx,
|
||||
x0 + 0.5f * QUAD_POINT_SIGNS[k][0] * strokeWeight,
|
||||
y0 + 0.5f * QUAD_POINT_SIGNS[k][1] * strokeWeight,
|
||||
0, rgba);
|
||||
0, rgba, clamp);
|
||||
vertIdx++;
|
||||
}
|
||||
|
||||
@@ -10679,6 +10678,15 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
lastPointIndexCache = lastPolyIndexCache = index;
|
||||
}
|
||||
|
||||
boolean clamp2D() {
|
||||
return is2D && tess.renderMode == IMMEDIATE &&
|
||||
zero(modelview.m01) && zero(modelview.m10);
|
||||
}
|
||||
|
||||
boolean clampSquarePoints2D() {
|
||||
return clamp2D();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
//
|
||||
// Line tessellation
|
||||
@@ -10714,11 +10722,22 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i0 = first + 2 * ln + 0;
|
||||
int i1 = first + 2 * ln + 1;
|
||||
index = addLine3D(i0, i1, index, null, false);
|
||||
index = addLineSegment3D(i0, i1, index, null, false);
|
||||
}
|
||||
lastLineIndexCache = index;
|
||||
}
|
||||
|
||||
boolean segmentIsAxisAligned(int i0, int i1) {
|
||||
float x0 = in.vertices[3 * i0 + 0];
|
||||
float y0 = in.vertices[3 * i0 + 1];
|
||||
|
||||
float x1 = in.vertices[3 * i1 + 0];
|
||||
float y1 = in.vertices[3 * i1 + 1];
|
||||
|
||||
return zero(x0 - x1) || zero(y0 - y1);
|
||||
}
|
||||
|
||||
|
||||
void tessellateLines2D(int lineCount) {
|
||||
int nvert = lineCount * 4;
|
||||
int nind = lineCount * 2 * 3;
|
||||
@@ -10731,10 +10750,11 @@ 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.
|
||||
boolean clamp = clampLines2D(lineCount);
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i0 = first + 2 * ln + 0;
|
||||
int i1 = first + 2 * ln + 1;
|
||||
index = addLine2D(i0, i1, index, false);
|
||||
index = addLineSegment2D(i0, i1, index, false, clamp);
|
||||
}
|
||||
lastLineIndexCache = lastPolyIndexCache = index;
|
||||
} else { // full stroking algorithm
|
||||
@@ -10751,6 +10771,19 @@ 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;
|
||||
res &= segmentIsAxisAligned(i0, i1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void tessellateLineStrip() {
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
if (stroke && 2 <= nInVert) {
|
||||
@@ -10781,9 +10814,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i1 = in.firstVertex + ln + 1;
|
||||
if (0 < nBevelTr) {
|
||||
index = addLine3D(i0, i1, index, lastInd, false);
|
||||
index = addLineSegment3D(i0, i1, index, lastInd, false);
|
||||
} else {
|
||||
index = addLine3D(i0, i1, index, null, false);
|
||||
index = addLineSegment3D(i0, i1, index, null, false);
|
||||
}
|
||||
i0 = i1;
|
||||
}
|
||||
@@ -10802,9 +10835,10 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
firstLineIndexCache = index;
|
||||
if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index.
|
||||
int i0 = in.firstVertex;
|
||||
boolean clamp = clampLineStrip2D(lineCount);
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i1 = in.firstVertex + ln + 1;
|
||||
index = addLine2D(i0, i1, index, false);
|
||||
index = addLineSegment2D(i0, i1, index, false, clamp);
|
||||
i0 = i1;
|
||||
}
|
||||
lastLineIndexCache = lastPolyIndexCache = index;
|
||||
@@ -10822,6 +10856,18 @@ 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);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void tessellateLineLoop() {
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
if (stroke && 2 <= nInVert) {
|
||||
@@ -10853,14 +10899,15 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
for (int ln = 0; ln < lineCount - 1; ln++) {
|
||||
int i1 = in.firstVertex + ln + 1;
|
||||
if (0 < nBevelTr) {
|
||||
index = addLine3D(i0, i1, index, lastInd, false);
|
||||
index = addLineSegment3D(i0, i1, index, lastInd, false);
|
||||
if (ln == 0) firstInd = (short)(lastInd[0] - 2);
|
||||
} else {
|
||||
index = addLine3D(i0, i1, index, null, false);
|
||||
index = addLineSegment3D(i0, i1, index, null, false);
|
||||
}
|
||||
i0 = i1;
|
||||
}
|
||||
index = addLine3D(in.lastVertex, in.firstVertex, index, lastInd, false);
|
||||
index = addLineSegment3D(in.lastVertex, in.firstVertex, index, lastInd,
|
||||
false);
|
||||
if (0 < nBevelTr) {
|
||||
index = addBevel3D(in.firstVertex, index, lastInd, firstInd, false);
|
||||
}
|
||||
@@ -10879,12 +10926,14 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
firstLineIndexCache = index;
|
||||
if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index.
|
||||
int i0 = in.firstVertex;
|
||||
boolean clamp = clampLineLoop2D(lineCount);
|
||||
for (int ln = 0; ln < lineCount - 1; ln++) {
|
||||
int i1 = in.firstVertex + ln + 1;
|
||||
index = addLine2D(i0, i1, index, false);
|
||||
index = addLineSegment2D(i0, i1, index, false, clamp);
|
||||
i0 = i1;
|
||||
}
|
||||
index = addLine2D(in.lastVertex, in.firstVertex, index, false);
|
||||
index = addLineSegment2D(in.lastVertex, in.firstVertex, index, false,
|
||||
clamp);
|
||||
lastLineIndexCache = lastPolyIndexCache = index;
|
||||
} else { // full stroking algorithm
|
||||
int first = in.firstVertex;
|
||||
@@ -10901,6 +10950,18 @@ 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);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void tessellateEdges() {
|
||||
if (stroke) {
|
||||
if (in.edgeCount == 0) return;
|
||||
@@ -10935,14 +10996,14 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
index = addBevel3D(edge[1], index, lastInd, firstInd, false);
|
||||
lastInd[0] = lastInd[1] = -1; // No join with next line segment.
|
||||
} else {
|
||||
index = addLine3D(i0, i1, index, lastInd, false);
|
||||
index = addLineSegment3D(i0, i1, index, lastInd, false);
|
||||
if (edge[2] == EDGE_START) firstInd = (short)(lastInd[0] - 2);
|
||||
if (edge[2] == EDGE_STOP || edge[2] == EDGE_SINGLE) {
|
||||
lastInd[0] = lastInd[1] = -1; // No join with next line segment.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
index = addLine3D(i0, i1, index, null, false);
|
||||
index = addLineSegment3D(i0, i1, index, null, false);
|
||||
}
|
||||
}
|
||||
lastLineIndexCache = index;
|
||||
@@ -10959,12 +11020,13 @@ 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.
|
||||
boolean clamp = clampEdges2D();
|
||||
for (int i = in.firstEdge; i <= in.lastEdge; 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];
|
||||
int i1 = edge[1];
|
||||
index = addLine2D(i0, i1, index, false);
|
||||
index = addLineSegment2D(i0, i1, index, false, clamp);
|
||||
}
|
||||
lastLineIndexCache = lastPolyIndexCache = index;
|
||||
} else { // full stroking algorithm
|
||||
@@ -11007,9 +11069,23 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
}
|
||||
|
||||
boolean clampEdges2D() {
|
||||
boolean res = clamp2D();
|
||||
if (res) {
|
||||
for (int i = in.firstEdge; i <= in.lastEdge; 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];
|
||||
int i1 = edge[1];
|
||||
res &= segmentIsAxisAligned(i0, i1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Adding the data that defines a quad starting at vertex i0 and
|
||||
// ending at i1.
|
||||
int addLine3D(int i0, int i1, int index, short[] lastInd,
|
||||
int addLineSegment3D(int i0, int i1, int index, short[] lastInd,
|
||||
boolean constStroke) {
|
||||
IndexCache cache = tess.lineIndexCache;
|
||||
int count = cache.vertexCount[index];
|
||||
@@ -11139,7 +11215,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
// Adding the data that defines a quad starting at vertex i0 and
|
||||
// ending at i1, in the case of pure 2D renderers (line geometry
|
||||
// is added to the poly arrays).
|
||||
int addLine2D(int i0, int i1, int index, boolean constStroke) {
|
||||
int addLineSegment2D(int i0, int i1, int index,
|
||||
boolean constStroke, boolean clampXY) {
|
||||
IndexCache cache = tess.polyIndexCache;
|
||||
int count = cache.vertexCount[index];
|
||||
if (PGL.MAX_VERTEX_INDEX1 <= count + 4) {
|
||||
@@ -11152,7 +11229,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
int color = constStroke ? strokeColor : in.strokeColors[i0];
|
||||
float weight = constStroke ? strokeWeight : in.strokeWeights[i0];
|
||||
if (subPixelStroke(weight)) clampingEnabled = false;
|
||||
if (subPixelStroke(weight)) clampXY = false;
|
||||
|
||||
float x0 = in.vertices[3 * i0 + 0];
|
||||
float y0 = in.vertices[3 * i0 + 1];
|
||||
@@ -11183,14 +11260,14 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
float normdy = normy * weight/2;
|
||||
|
||||
tess.setPolyVertex(vidx++, x0 + normdx - dirdx, y0 + normdy - dirdy,
|
||||
0, color);
|
||||
0, color, clampXY);
|
||||
tess.polyIndices[iidx++] = (short) (count + 0);
|
||||
|
||||
tess.setPolyVertex(vidx++, x0 - normdx - dirdx, y0 - normdy - dirdy,
|
||||
0, color);
|
||||
0, color, clampXY);
|
||||
tess.polyIndices[iidx++] = (short) (count + 1);
|
||||
|
||||
if (clampingEnabled) {
|
||||
if (clampXY) {
|
||||
// Check for degeneracy due to coordinate clamping
|
||||
float xac = tess.polyVertices[4 * (vidx - 2) + 0];
|
||||
float yac = tess.polyVertices[4 * (vidx - 2) + 1];
|
||||
@@ -11207,11 +11284,11 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
weight = in.strokeWeights[i1];
|
||||
normdx = normx * weight/2;
|
||||
normdy = normy * weight/2;
|
||||
if (subPixelStroke(weight)) clampingEnabled = false;
|
||||
if (subPixelStroke(weight)) clampXY = false;
|
||||
}
|
||||
|
||||
tess.setPolyVertex(vidx++, x1 - normdx + dirdx, y1 - normdy + dirdy,
|
||||
0, color);
|
||||
0, color, clampXY);
|
||||
tess.polyIndices[iidx++] = (short) (count + 2);
|
||||
|
||||
// Starting a new triangle re-using prev vertices.
|
||||
@@ -11219,10 +11296,10 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
tess.polyIndices[iidx++] = (short) (count + 0);
|
||||
|
||||
tess.setPolyVertex(vidx++, x1 + normdx + dirdx, y1 + normdy + dirdy,
|
||||
0, color);
|
||||
0, color, clampXY);
|
||||
tess.polyIndices[iidx++] = (short) (count + 3);
|
||||
|
||||
if (clampingEnabled) {
|
||||
if (clampXY) {
|
||||
// Check for degeneracy due to coordinate clamping
|
||||
float xac = tess.polyVertices[4 * (vidx - 2) + 0];
|
||||
float yac = tess.polyVertices[4 * (vidx - 2) + 1];
|
||||
@@ -11235,8 +11312,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
|
||||
cache.incCounts(index, 6, 4);
|
||||
|
||||
clampingEnabled = true;
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -11307,15 +11382,23 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int nInInd = nInVert;
|
||||
setRawSize(nInInd);
|
||||
int idx = 0;
|
||||
boolean clamp = clampTriangles();
|
||||
for (int i = in.firstVertex; i <= in.lastVertex; i++) {
|
||||
rawIndices[idx++] = i;
|
||||
}
|
||||
splitRawIndices();
|
||||
splitRawIndices(clamp);
|
||||
}
|
||||
endTex();
|
||||
tessellateEdges();
|
||||
}
|
||||
|
||||
boolean clampTriangles() {
|
||||
boolean res = clamp2D();
|
||||
if (res) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void tessellateTriangles(int[] indices) {
|
||||
beginTex();
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
@@ -11323,12 +11406,20 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int nInInd = indices.length;
|
||||
setRawSize(nInInd);
|
||||
PApplet.arrayCopy(indices, rawIndices, nInInd);
|
||||
splitRawIndices();
|
||||
boolean clamp = clampTriangles(indices);
|
||||
splitRawIndices(clamp);
|
||||
}
|
||||
endTex();
|
||||
tessellateEdges();
|
||||
}
|
||||
|
||||
boolean clampTriangles(int[] indices) {
|
||||
boolean res = clamp2D();
|
||||
if (res) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void tessellateTriangleFan() {
|
||||
beginTex();
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
@@ -11336,17 +11427,25 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
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;
|
||||
rawIndices[idx++] = i;
|
||||
rawIndices[idx++] = i + 1;
|
||||
}
|
||||
splitRawIndices();
|
||||
splitRawIndices(clamp);
|
||||
}
|
||||
endTex();
|
||||
tessellateEdges();
|
||||
}
|
||||
|
||||
boolean clampTriangleFan() {
|
||||
boolean res = clamp2D();
|
||||
if (res) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void tessellateTriangleStrip() {
|
||||
beginTex();
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
@@ -11354,6 +11453,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int nInInd = 3 * (nInVert - 2);
|
||||
setRawSize(nInInd);
|
||||
int idx = 0;
|
||||
boolean clamp = clampTriangleStrip();
|
||||
for (int i = in.firstVertex + 1; i < in.lastVertex; i++) {
|
||||
rawIndices[idx++] = i;
|
||||
if (i % 2 == 0) {
|
||||
@@ -11364,12 +11464,19 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
rawIndices[idx++] = i - 1;
|
||||
}
|
||||
}
|
||||
splitRawIndices();
|
||||
splitRawIndices(clamp);
|
||||
}
|
||||
endTex();
|
||||
tessellateEdges();
|
||||
}
|
||||
|
||||
boolean clampTriangleStrip() {
|
||||
boolean res = clamp2D();
|
||||
if (res) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void tessellateQuads() {
|
||||
beginTex();
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
@@ -11378,6 +11485,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
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;
|
||||
@@ -11392,12 +11500,29 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
rawIndices[idx++] = i3;
|
||||
rawIndices[idx++] = i0;
|
||||
}
|
||||
splitRawIndices();
|
||||
splitRawIndices(clamp);
|
||||
}
|
||||
endTex();
|
||||
tessellateEdges();
|
||||
}
|
||||
|
||||
boolean clampQuads(int quadCount) {
|
||||
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;
|
||||
res &= segmentIsAxisAligned(i0, i1) &&
|
||||
segmentIsAxisAligned(i1, i2) &&
|
||||
segmentIsAxisAligned(i2, i3);
|
||||
}
|
||||
}
|
||||
PApplet.println("quads are axis aligned " + res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void tessellateQuadStrip() {
|
||||
beginTex();
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
@@ -11406,6 +11531,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int nInInd = 6 * quadCount;
|
||||
setRawSize(nInInd);
|
||||
int idx = 0;
|
||||
boolean clamp = clampQuadStrip();
|
||||
for (int qd = 1; qd < nInVert / 2; qd++) {
|
||||
int i0 = in.firstVertex + 2 * (qd - 1);
|
||||
int i1 = in.firstVertex + 2 * (qd - 1) + 1;
|
||||
@@ -11420,12 +11546,19 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
rawIndices[idx++] = i2;
|
||||
rawIndices[idx++] = i3;
|
||||
}
|
||||
splitRawIndices();
|
||||
splitRawIndices(clamp);
|
||||
}
|
||||
endTex();
|
||||
tessellateEdges();
|
||||
}
|
||||
|
||||
boolean clampQuadStrip() {
|
||||
boolean res = clamp2D();
|
||||
if (res) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Uses the raw indices to split the geometry into contiguous
|
||||
// index groups when the vertex indices become too large. The basic
|
||||
// idea of this algorithm is to scan through the array of raw indices
|
||||
@@ -11442,7 +11575,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
// http://gameangst.com/?p=9
|
||||
// http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
|
||||
// http://www.ludicon.com/castano/blog/2009/02/optimal-grid-rendering/
|
||||
void splitRawIndices() {
|
||||
void splitRawIndices(boolean clampXY) {
|
||||
tess.polyIndexCheck(rawSize);
|
||||
int offset = tess.firstPolyIndex;
|
||||
|
||||
@@ -11522,17 +11655,17 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
if (inMaxVertRef <= inMaxVert1) {
|
||||
// Copy non-duplicated vertices from current region first
|
||||
tess.addPolyVertices(in, inMaxVertRef, inMaxVert1);
|
||||
tess.addPolyVertices(in, inMaxVertRef, inMaxVert1, clampXY);
|
||||
nondupCount = inMaxVert1 - inMaxVertRef + 1;
|
||||
}
|
||||
|
||||
// Copy duplicated vertices from previous regions last
|
||||
for (int i = 0; i < dupCount; i++) {
|
||||
tess.addPolyVertex(in, dupIndices[i] + inMaxVertRef);
|
||||
tess.addPolyVertex(in, dupIndices[i] + inMaxVertRef, clampXY);
|
||||
}
|
||||
} else {
|
||||
// Copy non-duplicated vertices from current region first
|
||||
tess.addPolyVertices(in, inMaxVert0, inMaxVert1);
|
||||
tess.addPolyVertices(in, inMaxVert0, inMaxVert1, clampXY);
|
||||
nondupCount = inMaxVert1 - inMaxVert0 + 1;
|
||||
}
|
||||
|
||||
@@ -11664,7 +11797,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
if (fill && 3 <= nInVert) {
|
||||
firstPolyIndexCache = -1;
|
||||
|
||||
callback.init(in.renderMode == RETAINED, false, calcNormals);
|
||||
boolean clamp = clampPolygon();
|
||||
callback.init(in.renderMode == RETAINED, false, calcNormals, clamp);
|
||||
|
||||
gluTess.beginPolygon();
|
||||
|
||||
@@ -11727,11 +11861,17 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
tessellateEdges();
|
||||
}
|
||||
|
||||
boolean clampPolygon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tessellates the path given as parameter. This will work only in 2D.
|
||||
// Based on the opengl stroke hack described here:
|
||||
// http://wiki.processing.org/w/Stroke_attributes_in_OpenGL
|
||||
public void tessellateLinePath(LinePath path) {
|
||||
callback.init(in.renderMode == RETAINED, true, false);
|
||||
boolean clamp = clampLinePath();
|
||||
|
||||
callback.init(in.renderMode == RETAINED, true, false, clamp);
|
||||
|
||||
int cap = strokeCap == ROUND ? LinePath.CAP_ROUND :
|
||||
strokeCap == PROJECT ? LinePath.CAP_SQUARE :
|
||||
@@ -11740,8 +11880,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
strokeJoin == BEVEL ? LinePath.JOIN_BEVEL :
|
||||
LinePath.JOIN_MITER;
|
||||
|
||||
if (subPixelStroke(strokeWeight)) clampingEnabled = false;
|
||||
|
||||
// Make the outline of the stroke from the path
|
||||
LinePath strokedPath = LinePath.createStrokedPath(path, strokeWeight,
|
||||
cap, join);
|
||||
@@ -11788,8 +11926,12 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
iter.next();
|
||||
}
|
||||
gluTess.endPolygon();
|
||||
}
|
||||
|
||||
clampingEnabled = true;
|
||||
boolean clampLinePath() {
|
||||
return clamp2D() &&
|
||||
strokeCap == PROJECT && strokeJoin == BEVEL &&
|
||||
!subPixelStroke(strokeWeight);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
@@ -11810,15 +11952,18 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected class TessellatorCallback implements PGL.TessellatorCallback {
|
||||
boolean calcNormals;
|
||||
boolean strokeTess;
|
||||
boolean clampXY;
|
||||
IndexCache cache;
|
||||
int cacheIndex;
|
||||
int vertFirst;
|
||||
int vertCount;
|
||||
int primitive;
|
||||
|
||||
public void init(boolean addCache, boolean strokeTess, boolean calcNorm) {
|
||||
public void init(boolean addCache, boolean strokeTess, boolean calcNorm,
|
||||
boolean clampXY) {
|
||||
this.strokeTess = strokeTess;
|
||||
this.calcNormals = calcNorm;
|
||||
this.clampXY = clampXY;
|
||||
|
||||
cache = tess.polyIndexCache;
|
||||
if (addCache) {
|
||||
@@ -11949,7 +12094,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
(float) d[ 7], (float) d[ 8], (float) d[ 9],
|
||||
(float) d[10], (float) d[11],
|
||||
acolor, scolor, ecolor,
|
||||
(float) d[24]);
|
||||
(float) d[24], clampXY);
|
||||
|
||||
vertCount++;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user