浏览代码

[libgdx] Remove Array.add, avoid copying

badlogic 8 年之前
父节点
当前提交
242eaf2bcc

+ 2 - 2
spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SoftwareClippingTest.java

@@ -183,11 +183,11 @@ public class SoftwareClippingTest extends ApplicationAdapter {
 		
 		
 		// must duplicate first vertex at end of polygon
 		// must duplicate first vertex at end of polygon
 		// so we can avoid module/branch in clipping code
 		// so we can avoid module/branch in clipping code
+		SutherlandHodgmanClipper.makeClockwise(clippingPolygon);
 		clippingPolygon.add(clippingPolygon.get(0));
 		clippingPolygon.add(clippingPolygon.get(0));
 		clippingPolygon.add(clippingPolygon.get(1));
 		clippingPolygon.add(clippingPolygon.get(1));
 		
 		
-		boolean isClockwise = SutherlandHodgmanClipper.clockwise(clippingPolygon);
-		boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, clippingPolygon, clippedPolygon, isClockwise);
+		boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, clippingPolygon, clippedPolygon);
 		System.out.println("Clipped: " + clipped);
 		System.out.println("Clipped: " + clipped);
 		if (clipped) {
 		if (clipped) {
 			clippedPolygonVertices.clear();
 			clippedPolygonVertices.clear();

+ 122 - 76
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java

@@ -152,15 +152,16 @@ public class SkeletonRenderer {
 		Texture texture = null;
 		Texture texture = null;
 		Color color = null, skeletonColor = skeleton.color;
 		Color color = null, skeletonColor = skeleton.color;
 		float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a;
 		float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a;
-		Array<Slot> drawOrder = skeleton.drawOrder;
+		Array<Slot> drawOrder = skeleton.drawOrder;		
 		for (int i = 0, n = drawOrder.size; i < n; i++) {
 		for (int i = 0, n = drawOrder.size; i < n; i++) {
+			final int vertexSize = (softwareClipping && clipAttachment != null) ? 2 : 5;
 			Slot slot = drawOrder.get(i);
 			Slot slot = drawOrder.get(i);
-			Attachment attachment = slot.attachment;
+			Attachment attachment = slot.attachment;			
 			if (attachment instanceof RegionAttachment) {
 			if (attachment instanceof RegionAttachment) {
 				RegionAttachment region = (RegionAttachment) attachment;
 				RegionAttachment region = (RegionAttachment) attachment;
-				verticesLength = 20;
+				verticesLength = vertexSize << 2;
 				vertices = this.vertices.items;
 				vertices = this.vertices.items;
-				region.computeWorldVertices(slot.getBone(), vertices, 0, 5);
+				region.computeWorldVertices(slot.getBone(), vertices, 0, vertexSize);
 				triangles = quadTriangles;
 				triangles = quadTriangles;
 				texture = region.getRegion().getTexture();
 				texture = region.getRegion().getTexture();
 				uvs = region.getUVs();
 				uvs = region.getUVs();
@@ -169,9 +170,9 @@ public class SkeletonRenderer {
 			} else if (attachment instanceof MeshAttachment) {
 			} else if (attachment instanceof MeshAttachment) {
 				MeshAttachment mesh = (MeshAttachment) attachment;
 				MeshAttachment mesh = (MeshAttachment) attachment;
 				int count = mesh.getWorldVerticesLength();
 				int count = mesh.getWorldVerticesLength();
-				verticesLength = (count >> 1) * 5;
+				verticesLength = (count >> 1) * vertexSize;
 				vertices = this.vertices.setSize(verticesLength);
 				vertices = this.vertices.setSize(verticesLength);
-				mesh.computeWorldVertices(slot, 0, count, vertices, 0, 5);
+				mesh.computeWorldVertices(slot, 0, count, vertices, 0, vertexSize);
 				triangles = mesh.getTriangles();
 				triangles = mesh.getTriangles();
 				texture = mesh.getRegion().getTexture();
 				texture = mesh.getRegion().getTexture();
 				uvs = mesh.getUVs();
 				uvs = mesh.getUVs();
@@ -217,11 +218,6 @@ public class SkeletonRenderer {
 						| ((int) (b * slotColor.b * color.b * alpha) << 16) //
 						| ((int) (b * slotColor.b * color.b * alpha) << 16) //
 						| ((int) (g * slotColor.g * color.g * alpha) << 8) //
 						| ((int) (g * slotColor.g * color.g * alpha) << 8) //
 						| (int) (r * slotColor.r * color.r * alpha));
 						| (int) (r * slotColor.r * color.r * alpha));
-				for (int v = 2, u = 0; v < verticesLength; v += 5, u += 2) {
-					vertices[v] = c;
-					vertices[v + 1] = uvs[u];
-					vertices[v + 2] = uvs[u + 1];
-				}
 
 
 				BlendMode slotBlendMode = slot.data.getBlendMode();
 				BlendMode slotBlendMode = slot.data.getBlendMode();
 				if (slotBlendMode != blendMode) {
 				if (slotBlendMode != blendMode) {
@@ -230,12 +226,22 @@ public class SkeletonRenderer {
 				}
 				}
 				if (softwareClipping) {
 				if (softwareClipping) {
 					if (clipAttachment != null) {
 					if (clipAttachment != null) {
-						clipSoftware(vertices, 0, verticesLength, triangles, 0, triangles.length, clippedVertices, clippedTriangles, 0, c, false);
+						clipSoftware(vertices, 0, verticesLength, triangles, 0, triangles.length, uvs, 0, c, false, clippedVertices, clippedTriangles);
 						batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, clippedTriangles.size);
 						batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, clippedTriangles.size);
 					} else {
 					} else {
+						for (int v = 2, u = 0; v < verticesLength; v += 5, u += 2) {
+							vertices[v] = c;
+							vertices[v + 1] = uvs[u];
+							vertices[v + 2] = uvs[u + 1];
+						}
 						batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length);
 						batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length);
 					}
 					}
 				} else {
 				} else {
+					for (int v = 2, u = 0; v < verticesLength; v += 5, u += 2) {
+						vertices[v] = c;
+						vertices[v + 1] = uvs[u];
+						vertices[v + 2] = uvs[u + 1];
+					}
 					batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length);
 					batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length);
 				}
 				}
 			}
 			}
@@ -257,15 +263,16 @@ public class SkeletonRenderer {
 		Texture texture = null;
 		Texture texture = null;
 		Color color = null, skeletonColor = skeleton.color;
 		Color color = null, skeletonColor = skeleton.color;
 		float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a;
 		float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a;
-		Array<Slot> drawOrder = skeleton.drawOrder;
+		Array<Slot> drawOrder = skeleton.drawOrder;		
 		for (int i = 0, n = drawOrder.size; i < n; i++) {
 		for (int i = 0, n = drawOrder.size; i < n; i++) {
+			final int vertexSize = (softwareClipping && clipAttachment != null) ? 2 : 6;
 			Slot slot = drawOrder.get(i);
 			Slot slot = drawOrder.get(i);
 			Attachment attachment = slot.attachment;
 			Attachment attachment = slot.attachment;
 			if (attachment instanceof RegionAttachment) {
 			if (attachment instanceof RegionAttachment) {
 				RegionAttachment region = (RegionAttachment) attachment;
 				RegionAttachment region = (RegionAttachment) attachment;
-				verticesLength = 24;
+				verticesLength = vertexSize << 2;
 				vertices = this.vertices.items;
 				vertices = this.vertices.items;
-				region.computeWorldVertices(slot.getBone(), vertices, 0, 6);
+				region.computeWorldVertices(slot.getBone(), vertices, 0, vertexSize);
 				triangles = quadTriangles;
 				triangles = quadTriangles;
 				texture = region.getRegion().getTexture();
 				texture = region.getRegion().getTexture();
 				uvs = region.getUVs();
 				uvs = region.getUVs();
@@ -274,9 +281,9 @@ public class SkeletonRenderer {
 			} else if (attachment instanceof MeshAttachment) {
 			} else if (attachment instanceof MeshAttachment) {
 				MeshAttachment mesh = (MeshAttachment) attachment;
 				MeshAttachment mesh = (MeshAttachment) attachment;
 				int count = mesh.getWorldVerticesLength();
 				int count = mesh.getWorldVerticesLength();
-				verticesLength = count * 3;
+				verticesLength = count * (vertexSize >> 1);
 				vertices = this.vertices.setSize(verticesLength);
 				vertices = this.vertices.setSize(verticesLength);
-				mesh.computeWorldVertices(slot, 0, count, vertices, 0, 6);
+				mesh.computeWorldVertices(slot, 0, count, vertices, 0, vertexSize);
 				triangles = mesh.getTriangles();
 				triangles = mesh.getTriangles();
 				texture = mesh.getRegion().getTexture();
 				texture = mesh.getRegion().getTexture();
 				uvs = mesh.getUVs();
 				uvs = mesh.getUVs();
@@ -329,12 +336,6 @@ public class SkeletonRenderer {
 						((int) (b * darkColor.b * color.b * 255) << 16) //
 						((int) (b * darkColor.b * color.b * 255) << 16) //
 								| ((int) (g * darkColor.g * color.g * 255) << 8) //
 								| ((int) (g * darkColor.g * color.g * 255) << 8) //
 								| (int) (r * darkColor.r * color.r * 255));
 								| (int) (r * darkColor.r * color.r * 255));
-				for (int v = 2, u = 0; v < verticesLength; v += 6, u += 2) {
-					vertices[v] = light;
-					vertices[v + 1] = dark;
-					vertices[v + 2] = uvs[u];
-					vertices[v + 3] = uvs[u + 1];
-				}
 
 
 				BlendMode slotBlendMode = slot.data.getBlendMode();
 				BlendMode slotBlendMode = slot.data.getBlendMode();
 				if (slotBlendMode != blendMode) {
 				if (slotBlendMode != blendMode) {
@@ -344,12 +345,24 @@ public class SkeletonRenderer {
 				
 				
 				if (softwareClipping) {
 				if (softwareClipping) {
 					if (clipAttachment != null) {
 					if (clipAttachment != null) {
-						clipSoftware(vertices, 0, verticesLength, triangles, 0, triangles.length, clippedVertices, clippedTriangles, dark, light, true);
+						clipSoftware(vertices, 0, verticesLength, triangles, 0, triangles.length, uvs, dark, light, true, clippedVertices, clippedTriangles);
 						batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, clippedTriangles.size);
 						batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, clippedTriangles.size);
 					} else {
 					} else {
+						for (int v = 2, u = 0; v < verticesLength; v += 6, u += 2) {
+							vertices[v] = light;
+							vertices[v + 1] = dark;
+							vertices[v + 2] = uvs[u];
+							vertices[v + 3] = uvs[u + 1];
+						}
 						batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length);
 						batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length);
 					}
 					}
 				} else {
 				} else {
+					for (int v = 2, u = 0; v < verticesLength; v += 6, u += 2) {
+						vertices[v] = light;
+						vertices[v + 1] = dark;
+						vertices[v + 2] = uvs[u];
+						vertices[v + 3] = uvs[u + 1];
+					}
 					batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length);
 					batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length);
 				}
 				}
 			}
 			}
@@ -408,33 +421,32 @@ public class SkeletonRenderer {
 		if (!softwareClipping) Gdx.gl.glDisable(GL20.GL_STENCIL_TEST);
 		if (!softwareClipping) Gdx.gl.glDisable(GL20.GL_STENCIL_TEST);
 	}
 	}
 	
 	
-	private void clipSoftware(final float[] vertices, final int offset, final int verticesLength, final short[] triangles, final int triangleOffset, final int trianglesLength, final FloatArray clippedVertices, final ShortArray clippedTriangles, final float dark, final float light, final boolean twoColor) {
-		int idx = 0;
+	private void clipSoftware(final float[] vertices, final int offset, final int verticesLength, final short[] triangles, final int triangleOffset, final int trianglesLength, final float uvs[], final float dark, final float light, final boolean twoColor, final FloatArray clippedVertices, final ShortArray clippedTriangles) {
+		short idx = 0;
 		clippedVertices.clear();
 		clippedVertices.clear();
 		clippedTriangles.clear();
 		clippedTriangles.clear();
-		final int vertexSize = twoColor ? 6 : 5;
-		final int uvOffset = twoColor ? 4 : 3;
 		for (int i = 0; i < trianglesLength; i += 3) {
 		for (int i = 0; i < trianglesLength; i += 3) {
-			int triOffset = triangles[i] * vertexSize;
-			float x1 = vertices[triOffset];
-			float y1= vertices[triOffset + 1];
-			float u1 = vertices[triOffset + uvOffset];
-			float v1 = vertices[triOffset + uvOffset + 1];
+			int vertexOffset = triangles[i] << 1;
+			float x1 = vertices[vertexOffset];
+			float y1= vertices[vertexOffset + 1];
+			float u1 = uvs[vertexOffset];
+			float v1 = uvs[vertexOffset + 1];
 			
 			
-			triOffset = triangles[i + 1] * vertexSize;
-			float x2 = vertices[triOffset];
-			float y2 = vertices[triOffset + 1];
-			float u2 = vertices[triOffset + uvOffset];
-			float v2 = vertices[triOffset + uvOffset + 1];
+			vertexOffset = triangles[i + 1] << 1;
+			float x2 = vertices[vertexOffset];
+			float y2 = vertices[vertexOffset + 1];
+			float u2 = uvs[vertexOffset];
+			float v2 = uvs[vertexOffset + 1];
 			
 			
-			triOffset = triangles[i + 2] * vertexSize;
-			float x3 = vertices[triOffset];
-			float y3 = vertices[triOffset + 1];
-			float u3 = vertices[triOffset + uvOffset];
-			float v3 = vertices[triOffset + uvOffset + 1];
+			vertexOffset = triangles[i + 2] << 1;
+			float x3 = vertices[vertexOffset];
+			float y3 = vertices[vertexOffset + 1];
+			float u3 = uvs[vertexOffset];
+			float v3 = uvs[vertexOffset + 1];
 			
 			
-			boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, clippingArea, clipOutput, clippingAreaClockwise);
-			if (clipped) {				
+			boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, clippingArea, clipOutput);
+			if (clipped) {
+				if (clipOutput.size == 0) continue;
 				float d0 = y2 - y3;
 				float d0 = y2 - y3;
 				float d1 = x3 - x2;
 				float d1 = x3 - x2;
 				float d2 = x1 - x3;
 				float d2 = x1 - x3;
@@ -444,6 +456,9 @@ public class SkeletonRenderer {
 				float denom = 1 / (d0 * d2 + d1 * d3);
 				float denom = 1 / (d0 * d2 + d1 * d3);
 				
 				
 				float[] clipVertices = clipOutput.items;
 				float[] clipVertices = clipOutput.items;
+				int s = clippedVertices.size;
+				clippedVertices.setSize(s + (clipOutput.size >> 1) * (twoColor ? 6 : 5));
+				final float[] clippedVerticesArray = clippedVertices.items;
 				
 				
 				for (int j = 0, n = clipOutput.size; j < n; j += 2) {				
 				for (int j = 0, n = clipOutput.size; j < n; j += 2) {				
 					float x = clipVertices[j];
 					float x = clipVertices[j];
@@ -457,46 +472,77 @@ public class SkeletonRenderer {
 					
 					
 					float u = u1 * a + u2 * b + u3 * c;
 					float u = u1 * a + u2 * b + u3 * c;
 					float v = v1 * a + v2 * b + v3 * c;
 					float v = v1 * a + v2 * b + v3 * c;
-					clippedVertices.add(x);
-					clippedVertices.add(y);
-					clippedVertices.add(light);
-					if (twoColor) clippedVertices.add(dark);
-					clippedVertices.add(u);
-					clippedVertices.add(v);
+					clippedVerticesArray[s++] = x;
+					clippedVerticesArray[s++] = y;
+					clippedVerticesArray[s++] = light;
+					if (twoColor) clippedVerticesArray[s++] = dark;
+					clippedVerticesArray[s++] = u;
+					clippedVerticesArray[s++] = v;
 				}
 				}
 				
 				
+				s = clippedTriangles.size;
+				clippedTriangles.setSize(s + 3 * ((clipOutput.size >> 1) - 2));
+				final short[] clippedTrianglesArray = clippedTriangles.items;
+				
 				for (int j = 1, n = (clipOutput.size >> 1) - 1; j < n; j++) {
 				for (int j = 1, n = (clipOutput.size >> 1) - 1; j < n; j++) {
-					clippedTriangles.add(idx);
-					clippedTriangles.add(idx + j);
-					clippedTriangles.add(idx + j + 1);
+					clippedTrianglesArray[s++] = idx;
+					clippedTrianglesArray[s++] = (short)(idx + j);
+					clippedTrianglesArray[s++] = (short)(idx + j + 1);
 				}
 				}
 				
 				
 				idx += clipOutput.size >> 1;
 				idx += clipOutput.size >> 1;
 			} else {
 			} else {
-				clippedVertices.add(x1);
-				clippedVertices.add(y1);
-				clippedVertices.add(light);
-				if (twoColor) clippedVertices.add(dark);
-				clippedVertices.add(u1);
-				clippedVertices.add(v1);
-				
-				clippedVertices.add(x2);
-				clippedVertices.add(y2);
-				clippedVertices.add(light);
-				if (twoColor) clippedVertices.add(dark);
-				clippedVertices.add(u2);
-				clippedVertices.add(v2);
+				int s = clippedVertices.size;
+				clippedVertices.setSize(s + 3 * (twoColor ? 6 : 5));
+				final float[] clippedVerticesArray = clippedVertices.items;
 				
 				
-				clippedVertices.add(x3);
-				clippedVertices.add(y3);
-				clippedVertices.add(light);
-				if (twoColor) clippedVertices.add(dark);
-				clippedVertices.add(u3);
-				clippedVertices.add(v3);
+				if (!twoColor) { 
+					clippedVerticesArray[s] = x1;
+					clippedVerticesArray[s + 1] = y1;
+					clippedVerticesArray[s + 2] = light;
+					clippedVerticesArray[s + 3] = u1;
+					clippedVerticesArray[s + 4] = v1;
+					
+					clippedVerticesArray[s + 5] = x2;
+					clippedVerticesArray[s + 6] = y2;
+					clippedVerticesArray[s + 7] = light;
+					clippedVerticesArray[s + 8] = u2;
+					clippedVerticesArray[s + 9] = v2;
+					
+					clippedVerticesArray[s + 10] = x3;
+					clippedVerticesArray[s + 11] = y3;
+					clippedVerticesArray[s + 12] = light;
+					clippedVerticesArray[s + 13] = u3;
+					clippedVerticesArray[s + 14] = v3;
+				} else {
+					clippedVerticesArray[s] = x1;
+					clippedVerticesArray[s + 1] = y1;
+					clippedVerticesArray[s + 2] = light;
+					clippedVerticesArray[s + 3] = dark;
+					clippedVerticesArray[s + 4] = u1;
+					clippedVerticesArray[s + 5] = v1;
+					
+					clippedVerticesArray[s + 6] = x2;
+					clippedVerticesArray[s + 7] = y2;
+					clippedVerticesArray[s + 8] = light;
+					clippedVerticesArray[s + 9] = dark;
+					clippedVerticesArray[s + 10] = u2;
+					clippedVerticesArray[s + 11] = v2;
+					
+					clippedVerticesArray[s + 12] = x3;
+					clippedVerticesArray[s + 13] = y3;
+					clippedVerticesArray[s + 14] = light;
+					clippedVerticesArray[s + 15] = dark;
+					clippedVerticesArray[s + 16] = u3;
+					clippedVerticesArray[s + 17] = v3;
+				}
 				
 				
-				clippedTriangles.add(idx++);
-				clippedTriangles.add(idx++);
-				clippedTriangles.add(idx++);
+				s = clippedTriangles.size;
+				clippedTriangles.setSize(s + 3);
+				final short[] clippedTrianglesArray = clippedTriangles.items;
+				clippedTrianglesArray[s] = idx++;
+				clippedTrianglesArray[s + 1] = idx++;
+				clippedTrianglesArray[s + 2] = idx++;
 			}
 			}
 		}
 		}
 	}
 	}

+ 1 - 2
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/SutherlandHodgmanClipper.java

@@ -8,8 +8,7 @@ public class SutherlandHodgmanClipper {
 
 
 	/** Clips the input triangle against the convex clipping area, which needs to be clockwise. If the triangle lies entirely within the clipping area, false is
 	/** Clips the input triangle against the convex clipping area, which needs to be clockwise. If the triangle lies entirely within the clipping area, false is
 	 * returned. The clipping area must duplicate the first vertex at the end of the vertices list! */
 	 * returned. The clipping area must duplicate the first vertex at the end of the vertices list! */
-	public boolean clip (float x1, float y1, float x2, float y2, float x3, float y3, FloatArray clippingArea, FloatArray output,
-		boolean isClockwise) {
+	public boolean clip (float x1, float y1, float x2, float y2, float x3, float y3, FloatArray clippingArea, FloatArray output) {
 		final FloatArray originalOutput = output;
 		final FloatArray originalOutput = output;
 		boolean clipped = false;
 		boolean clipped = false;