implementing depth sorting

This commit is contained in:
codeanticode
2013-11-24 01:39:37 -05:00
parent 27e05e8025
commit f76f0758e4
@@ -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();
}