mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
implementing depth sorting
This commit is contained in:
@@ -2423,16 +2423,218 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
|
||||
|
||||
class Triangle {
|
||||
int i0, i1, i2;
|
||||
PImage tex;
|
||||
float dist;
|
||||
Triangle(int i0, int i1, int i2, PImage tex, float dist) {
|
||||
this.i0 = i0;
|
||||
this.i1 = i1;
|
||||
this.i2 = i2;
|
||||
this.tex = tex;
|
||||
this.dist = dist;
|
||||
}
|
||||
}
|
||||
// Adapted from Ben Van Citters code:
|
||||
// http://openprocessing.org/sketch/100912
|
||||
Triangle[] sortedPolyTriangles = null;
|
||||
int sortedTriangleCount = 0;
|
||||
void sortTriangles() {
|
||||
if (sortedPolyTriangles == null) {
|
||||
sortedPolyTriangles = new Triangle[512];
|
||||
}
|
||||
|
||||
float[] vertices = tessGeo.polyVertices;
|
||||
short[] indices = tessGeo.polyIndices;
|
||||
float[] src0 = {0, 0, 0, 0};
|
||||
float[] src1 = {0, 0, 0, 0};
|
||||
float[] src2 = {0, 0, 0, 0};
|
||||
float[] pt0 = {0, 0, 0, 0};
|
||||
float[] pt1 = {0, 0, 0, 0};
|
||||
float[] pt2 = {0, 0, 0, 0};
|
||||
|
||||
sortedTriangleCount = 0;
|
||||
for (int i = 0; i < texCache.size; i++) {
|
||||
PImage textureImage = texCache.getTextureImage(i);
|
||||
int first = texCache.firstCache[i];
|
||||
int last = texCache.lastCache[i];
|
||||
IndexCache cache = tessGeo.polyIndexCache;
|
||||
for (int n = first; n <= last; n++) {
|
||||
int ioffset = n == first ? texCache.firstIndex[i] :
|
||||
cache.indexOffset[n];
|
||||
int icount = n == last ? texCache.lastIndex[i] - ioffset + 1 :
|
||||
cache.indexOffset[n] + cache.indexCount[n] -
|
||||
ioffset;
|
||||
int voffset = cache.vertexOffset[n];
|
||||
for (int tr = ioffset / 3; tr < (ioffset + icount) / 3; tr++) {
|
||||
if (sortedPolyTriangles.length == sortedTriangleCount) {
|
||||
// expand array
|
||||
int newSize = sortedTriangleCount << 1;
|
||||
Triangle[] temp = new Triangle[newSize];
|
||||
PApplet.arrayCopy(sortedPolyTriangles, 0, temp, 0, newSize);
|
||||
sortedPolyTriangles = temp;
|
||||
}
|
||||
|
||||
int i0 = voffset + indices[3 * tr + 0];
|
||||
int i1 = voffset + indices[3 * tr + 1];
|
||||
int i2 = voffset + indices[3 * tr + 2];
|
||||
PApplet.arrayCopy(vertices, 4 * i0, src0, 0, 4);
|
||||
PApplet.arrayCopy(vertices, 4 * i1, src1, 0, 4);
|
||||
PApplet.arrayCopy(vertices, 4 * i2, src2, 0, 4);
|
||||
modelview.mult(src0, pt0);
|
||||
modelview.mult(src1, pt1);
|
||||
modelview.mult(src2, pt2);
|
||||
// add all three verts together and divide... could use another determination
|
||||
// of the 'depth' of the triangle such as min or max vert dist...
|
||||
float[] pos = new float[]{(pt0[X] + pt1[X] + pt2[X]) /3,
|
||||
(pt0[Y] + pt1[Y] + pt2[Y]) /3,
|
||||
(pt0[Z] + pt1[Z] + pt2[Z]) /3};
|
||||
|
||||
// pt0, pt1 and pt2 are in eye coordinates since they have been
|
||||
// multiplied by the modelview matrix.
|
||||
float d = PApplet.dist(0f, 0f, 0f, pos[0], pos[1], pos[2]);
|
||||
|
||||
Triangle tri = new Triangle(i0, i1, i2, textureImage, d);
|
||||
sortedPolyTriangles[sortedTriangleCount] = tri;
|
||||
sortedTriangleCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
quickSortTris(0, sortedTriangleCount - 1);
|
||||
}
|
||||
|
||||
// an 'in-place' implementation of quick I whipped together late at night
|
||||
// based off of the algorithm found on wikipedia: http://en.wikipedia.org/wiki/Quicksort
|
||||
private void quickSortTris(int leftI, int rightI) {
|
||||
if(leftI < rightI) {
|
||||
int pivotIndex = (leftI + rightI)/2;
|
||||
int newPivotIndex = partition(leftI,rightI,pivotIndex);
|
||||
quickSortTris(leftI, newPivotIndex-1);
|
||||
quickSortTris(newPivotIndex+1, rightI);
|
||||
}
|
||||
}
|
||||
|
||||
//part of quicksort
|
||||
private int partition(int leftIndex, int rightIndex, int pivotIndex) {
|
||||
float pivotVal = sortedPolyTriangles[pivotIndex].dist;
|
||||
swapTris(pivotIndex,rightIndex);
|
||||
int storeIndex = leftIndex;
|
||||
for(int i = leftIndex; i < rightIndex; i++)
|
||||
{
|
||||
if(sortedPolyTriangles[i].dist > pivotVal)
|
||||
{
|
||||
swapTris(i,storeIndex);
|
||||
storeIndex++;
|
||||
}
|
||||
}
|
||||
swapTris(rightIndex,storeIndex);
|
||||
return storeIndex;
|
||||
}
|
||||
|
||||
//part of quicksort
|
||||
private void swapTris(int a, int b) {
|
||||
Triangle tmp = sortedPolyTriangles[a];
|
||||
sortedPolyTriangles[a] = sortedPolyTriangles[b];
|
||||
sortedPolyTriangles[b] = tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void rawPolys() {
|
||||
raw.colorMode(RGB);
|
||||
raw.noStroke();
|
||||
raw.beginShape(TRIANGLES);
|
||||
|
||||
sortTriangles();
|
||||
|
||||
float[] vertices = tessGeo.polyVertices;
|
||||
int[] color = tessGeo.polyColors;
|
||||
float[] uv = tessGeo.polyTexCoords;
|
||||
short[] indices = tessGeo.polyIndices;
|
||||
|
||||
|
||||
sortTriangles();
|
||||
for (int i = 0; i < sortedTriangleCount; i++) {
|
||||
Triangle tri = sortedPolyTriangles[i];
|
||||
int i0 = tri.i0;
|
||||
int i1 = tri.i1;
|
||||
int i2 = tri.i2;
|
||||
PImage tex = tri.tex;
|
||||
|
||||
float[] pt0 = {0, 0, 0, 0};
|
||||
float[] pt1 = {0, 0, 0, 0};
|
||||
float[] pt2 = {0, 0, 0, 0};
|
||||
int argb0 = PGL.nativeToJavaARGB(color[i0]);
|
||||
int argb1 = PGL.nativeToJavaARGB(color[i1]);
|
||||
int argb2 = PGL.nativeToJavaARGB(color[i2]);
|
||||
|
||||
if (flushMode == FLUSH_CONTINUOUSLY) {
|
||||
float[] src0 = {0, 0, 0, 0};
|
||||
float[] src1 = {0, 0, 0, 0};
|
||||
float[] src2 = {0, 0, 0, 0};
|
||||
PApplet.arrayCopy(vertices, 4 * i0, src0, 0, 4);
|
||||
PApplet.arrayCopy(vertices, 4 * i1, src1, 0, 4);
|
||||
PApplet.arrayCopy(vertices, 4 * i2, src2, 0, 4);
|
||||
modelview.mult(src0, pt0);
|
||||
modelview.mult(src1, pt1);
|
||||
modelview.mult(src2, pt2);
|
||||
} else {
|
||||
PApplet.arrayCopy(vertices, 4 * i0, pt0, 0, 4);
|
||||
PApplet.arrayCopy(vertices, 4 * i1, pt1, 0, 4);
|
||||
PApplet.arrayCopy(vertices, 4 * i2, pt2, 0, 4);
|
||||
}
|
||||
|
||||
if (tex != null) {
|
||||
raw.texture(tex);
|
||||
if (raw.is3D()) {
|
||||
raw.fill(argb0);
|
||||
raw.vertex(pt0[X], pt0[Y], pt0[Z], uv[2 * i0 + 0], uv[2 * i0 + 1]);
|
||||
raw.fill(argb1);
|
||||
raw.vertex(pt1[X], pt1[Y], pt1[Z], uv[2 * i1 + 0], uv[2 * i1 + 1]);
|
||||
raw.fill(argb2);
|
||||
raw.vertex(pt2[X], pt2[Y], pt2[Z], uv[2 * i2 + 0], uv[2 * i2 + 1]);
|
||||
} else if (raw.is2D()) {
|
||||
float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]);
|
||||
float sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]);
|
||||
float sx1 = screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]);
|
||||
float sy1 = screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]);
|
||||
float sx2 = screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]);
|
||||
float sy2 = screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]);
|
||||
raw.fill(argb0);
|
||||
raw.vertex(sx0, sy0, uv[2 * i0 + 0], uv[2 * i0 + 1]);
|
||||
raw.fill(argb1);
|
||||
raw.vertex(sx1, sy1, uv[2 * i1 + 0], uv[2 * i1 + 1]);
|
||||
raw.fill(argb1);
|
||||
raw.vertex(sx2, sy2, uv[2 * i2 + 0], uv[2 * i2 + 1]);
|
||||
}
|
||||
} else {
|
||||
if (raw.is3D()) {
|
||||
raw.fill(argb0);
|
||||
raw.vertex(pt0[X], pt0[Y], pt0[Z]);
|
||||
raw.fill(argb1);
|
||||
raw.vertex(pt1[X], pt1[Y], pt1[Z]);
|
||||
raw.fill(argb2);
|
||||
raw.vertex(pt2[X], pt2[Y], pt2[Z]);
|
||||
} else if (raw.is2D()) {
|
||||
float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]);
|
||||
float sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]);
|
||||
float sx1 = screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]);
|
||||
float sy1 = screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]);
|
||||
float sx2 = screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]);
|
||||
float sy2 = screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]);
|
||||
raw.fill(argb0);
|
||||
raw.vertex(sx0, sy0);
|
||||
raw.fill(argb1);
|
||||
raw.vertex(sx1, sy1);
|
||||
raw.fill(argb2);
|
||||
raw.vertex(sx2, sy2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
for (int i = 0; i < texCache.size; i++) {
|
||||
PImage textureImage = texCache.getTextureImage(i);
|
||||
|
||||
@@ -2524,6 +2726,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
raw.endShape();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user