From 9ca215f2e9be8593e3dbecfa46f5b801642bf1b0 Mon Sep 17 00:00:00 2001 From: badlogic Date: Fri, 31 Mar 2017 11:18:39 +0200 Subject: [PATCH] [libgdx] Refactored SkeletonRenderer, moved clipping related code to SkeletonClipping, removed stencil clipping --- .../esotericsoftware/spine/ClippingTest.java | 26 +- .../spine/ConvexDecomposerTest.java | 2 +- .../spine/SkeletonClipping.java | 217 ++++++++++++++ .../spine/SkeletonRenderer.java | 279 ++---------------- 4 files changed, 253 insertions(+), 271 deletions(-) create mode 100644 spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonClipping.java diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ClippingTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ClippingTest.java index 901b0cd89..36133d7e2 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ClippingTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ClippingTest.java @@ -61,7 +61,6 @@ public class ClippingTest extends ApplicationAdapter { batch = new PolygonSpriteBatch(2048); renderer = new SkeletonRenderer(); renderer.setPremultipliedAlpha(true); - renderer.setSoftwareClipping(true); debugRenderer = new SkeletonRendererDebug(); debugRenderer.setBoundingBoxes(false); debugRenderer.setRegionAttachments(false); @@ -90,13 +89,13 @@ public class ClippingTest extends ApplicationAdapter { ClippingAttachment clip = new ClippingAttachment("clip"); // Rectangle: clip.setVertices( -// new float[] { 87, 288, 217, 371, 456, 361, 539, 175, 304, 194, 392, 290, 193, 214, 123, 15, 14, 137 }); - new float[] { // - -140, 50, // - 250, 50, // - 250, 350, // - -140, 350, // - }); + new float[] { 94.0f, 84.0f, 45.0f, 165.0f, 218.0f, 292.0f, 476.0f, 227.0f, 480.0f, 125.0f, 325.0f, 191.0f, 333.0f, 77.0f, 302.0f, 30.0f, 175.0f, 140.0f }); +// new float[] { // +// -140, 50, // +// 250, 50, // +// 250, 350, // +// -140, 350, // +// }); // Self intersection: // clip.setVertices(new float[] { // // -140, -50, // @@ -104,7 +103,11 @@ public class ClippingTest extends ApplicationAdapter { // 120, -50, // // -140, 50, // // }); - clip.setWorldVerticesLength(8); + for (int j = 0; j < clip.getVertices().length; j+=2) { + clip.getVertices()[j] = (clip.getVertices()[j] - 150f); + clip.getVertices()[j+1] = (clip.getVertices()[j+1] + 100); + } + clip.setWorldVerticesLength(clip.getVertices().length); clip.setEndSlot(skeleton.findSlot("front_hand").data.index); SlotData clipSlotData = new SlotData(skeletonData.getSlots().size, "clip slot", skeletonData.getBones().first()); @@ -139,11 +142,6 @@ public class ClippingTest extends ApplicationAdapter { batch.end(); debugRenderer.draw(skeleton); - - if (Gdx.input.isKeyJustPressed(Keys.S)) { - renderer.setSoftwareClipping(!renderer.getSoftwareClipping()); - System.out.println("Software clipping: " + renderer.getSoftwareClipping()); - } } public void resize (int width, int height) { diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ConvexDecomposerTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ConvexDecomposerTest.java index 2b5a50363..8557e45d4 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ConvexDecomposerTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ConvexDecomposerTest.java @@ -47,7 +47,7 @@ public class ConvexDecomposerTest extends ApplicationAdapter { image = new Texture("skin/skin.png"); font = new BitmapFont(); - float[] v = {100, 100, 120, 100, 200, 100, 200, 400, 100, 400}; + float[] v = new float[] { 94.0f, 84.0f, 45.0f, 165.0f, 218.0f, 292.0f, 476.0f, 227.0f, 480.0f, 125.0f, 325.0f, 191.0f, 333.0f, 77.0f, 302.0f, 30.0f, 175.0f, 140.0f }; // float[] v = {87, 288, 217, 371, 456, 361, 539, 175, 304, 194, 392, 290, 193, 214, 123, 15, 14, 137}; // float[] v = { 336, 153, 207, 184, 364, 333, 529, 326, 584, 130, 438, 224 }; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonClipping.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonClipping.java new file mode 100644 index 000000000..a2ccfc8fa --- /dev/null +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonClipping.java @@ -0,0 +1,217 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable, and + * non-transferable license to use, install, execute, and perform the Spine + * Runtimes software and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +package com.esotericsoftware.spine; + +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.FloatArray; +import com.badlogic.gdx.utils.ShortArray; +import com.esotericsoftware.spine.attachments.ClippingAttachment; +import com.esotericsoftware.spine.utils.Clipper; +import com.esotericsoftware.spine.utils.ConvexDecomposer; + +public class SkeletonClipping { + private ClippingAttachment clipAttachment; + private Clipper clipper = new Clipper(); + private ConvexDecomposer decomposer = new ConvexDecomposer(); + private FloatArray clippingPolygon = new FloatArray(400); + private Array convexClippingPolygons; + private FloatArray clipOutput = new FloatArray(400); + private FloatArray clippedVertices = new FloatArray(400); + private ShortArray clippedTriangles = new ShortArray(400); + + public void clipStart (Slot slot, ClippingAttachment clip) { + if (clipAttachment != null) return; + clipAttachment = clip; + + int n = clip.getWorldVerticesLength(); + float[] vertices = this.clippingPolygon.setSize(n); + clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); + convexClippingPolygons = decomposer.decompose(clippingPolygon); + for (FloatArray poly : convexClippingPolygons) { + Clipper.makeClockwise(poly); + poly.add(poly.items[0]); + poly.add(poly.items[1]); + } + } + + public void clipEnd () { + clippedVertices.clear(); + clippedTriangles.clear(); + clippingPolygon.clear(); + convexClippingPolygons = null; + clipAttachment = null; + } + + public boolean isClipping () { + return clipAttachment != null; + } + + public ClippingAttachment getClippingAttachment () { + return clipAttachment; + } + + public void clipTriangles (final float[] vertices, final int verticesLength, final short[] triangles, + final int trianglesLength, final float uvs[], final float dark, final float light, final boolean twoColor) { + short idx = 0; + clippedVertices.clear(); + clippedTriangles.clear(); + for (FloatArray convexClippingPolygon : convexClippingPolygons) { + for (int i = 0; i < trianglesLength; i += 3) { + int vertexOffset = triangles[i] << 1; + float x1 = vertices[vertexOffset]; + float y1 = vertices[vertexOffset + 1]; + float u1 = uvs[vertexOffset]; + float v1 = uvs[vertexOffset + 1]; + + vertexOffset = triangles[i + 1] << 1; + float x2 = vertices[vertexOffset]; + float y2 = vertices[vertexOffset + 1]; + float u2 = uvs[vertexOffset]; + float v2 = uvs[vertexOffset + 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, convexClippingPolygon, clipOutput); + if (clipped) { + if (clipOutput.size == 0) continue; + float d0 = y2 - y3; + float d1 = x3 - x2; + float d2 = x1 - x3; + float d3 = y1 - y3; + float d4 = y3 - y1; + + float denom = 1 / (d0 * d2 + d1 * d3); + + 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) { + float x = clipVertices[j]; + float y = clipVertices[j + 1]; + + float c0 = x - x3; + float c1 = y - y3; + float a = (d0 * c0 + d1 * c1) * denom; + float b = (d4 * c0 + d2 * c1) * denom; + float c = 1.0f - a - b; + + float u = u1 * a + u2 * b + u3 * c; + float v = v1 * a + v2 * b + v3 * c; + 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++) { + clippedTrianglesArray[s++] = idx; + clippedTrianglesArray[s++] = (short)(idx + j); + clippedTrianglesArray[s++] = (short)(idx + j + 1); + } + + idx += clipOutput.size >> 1; + } else { + int s = clippedVertices.size; + clippedVertices.setSize(s + 3 * (twoColor ? 6 : 5)); + final float[] clippedVerticesArray = clippedVertices.items; + + 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; + } + + s = clippedTriangles.size; + clippedTriangles.setSize(s + 3); + final short[] clippedTrianglesArray = clippedTriangles.items; + clippedTrianglesArray[s] = idx++; + clippedTrianglesArray[s + 1] = idx++; + clippedTrianglesArray[s + 2] = idx++; + } + } + } + } + + public FloatArray getClippedVertices () { + return clippedVertices; + } + + public ShortArray getClippedTriangles () { + return clippedTriangles; + } +} diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java index 113a04957..b882a9b9e 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java @@ -30,15 +30,11 @@ package com.esotericsoftware.spine; -import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer; -import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20; -import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.FloatArray; @@ -49,27 +45,16 @@ import com.esotericsoftware.spine.attachments.ClippingAttachment; import com.esotericsoftware.spine.attachments.MeshAttachment; import com.esotericsoftware.spine.attachments.RegionAttachment; import com.esotericsoftware.spine.attachments.SkeletonAttachment; -import com.esotericsoftware.spine.utils.Clipper; -import com.esotericsoftware.spine.utils.ConvexDecomposer; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; public class SkeletonRenderer implements Disposable { static private final short[] quadTriangles = {0, 1, 2, 2, 3, 0}; - private boolean softwareClipping; private boolean premultipliedAlpha; private final FloatArray vertices = new FloatArray(32); - private ClippingAttachment clipAttachment; - private Clipper clipper = new Clipper(); - private ConvexDecomposer decomposer = new ConvexDecomposer(); - private FloatArray clippingPolygon = new FloatArray(400); - private Array convexClippingPolygons; - private FloatArray clipOutput = new FloatArray(400); - private FloatArray clippedVertices = new FloatArray(400); - private ShortArray clippedTriangles = new ShortArray(400); - private final Matrix4 combinedMatrix = new Matrix4(); private ImmediateModeRenderer renderer; + private final SkeletonClipping clipper = new SkeletonClipping(); public void draw (Batch batch, Skeleton skeleton) { boolean premultipliedAlpha = this.premultipliedAlpha; @@ -102,9 +87,7 @@ public class SkeletonRenderer implements Disposable { } else if (attachment instanceof ClippingAttachment) { ClippingAttachment clip = (ClippingAttachment)attachment; - if (!softwareClipping) batch.end(); - clipStart(batch.getProjectionMatrix(), batch.getTransformMatrix(), slot, clip); - if (!softwareClipping) batch.begin(); + clipper.clipStart(slot, clip); continue; } else if (attachment instanceof MeshAttachment) { @@ -137,10 +120,7 @@ public class SkeletonRenderer implements Disposable { } } - if (clipAttachment != null && i == clipAttachment.getEndSlot()) { - batch.flush(); - clipEnd(); - } + if (clipper.isClipping() && clipper.getClippingAttachment().getEndSlot() == i) clipper.clipEnd(); } } @@ -156,7 +136,7 @@ public class SkeletonRenderer implements Disposable { float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a; Array drawOrder = skeleton.drawOrder; for (int i = 0, n = drawOrder.size; i < n; i++) { - final int vertexSize = (softwareClipping && clipAttachment != null) ? 2 : 5; + final int vertexSize = clipper.isClipping() ? 2 : 5; Slot slot = drawOrder.get(i); Attachment attachment = slot.attachment; if (attachment instanceof RegionAttachment) { @@ -182,9 +162,7 @@ public class SkeletonRenderer implements Disposable { } else if (attachment instanceof ClippingAttachment) { ClippingAttachment clip = (ClippingAttachment)attachment; - if (!softwareClipping) batch.end(); - clipStart(batch.getProjectionMatrix(), batch.getTransformMatrix(), slot, clip); - if (!softwareClipping) batch.begin(); + clipper.clipStart(slot, clip); continue; } else if (attachment instanceof SkeletonAttachment) { @@ -226,20 +204,13 @@ public class SkeletonRenderer implements Disposable { blendMode = slotBlendMode; batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); } - if (softwareClipping) { - if (clipAttachment != null) { - 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); - } 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); - } + + if (clipper.isClipping()) { + clipper.clipTriangles(vertices, verticesLength, triangles, triangles.length, uvs, 0, c, false); + FloatArray clippedVertices = clipper.getClippedVertices(); + ShortArray clippedTriangles = clipper.getClippedTriangles(); + batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, + clippedTriangles.size); } else { for (int v = 2, u = 0; v < verticesLength; v += 5, u += 2) { vertices[v] = c; @@ -250,10 +221,7 @@ public class SkeletonRenderer implements Disposable { } } - if (clipAttachment != null && i == clipAttachment.getEndSlot()) { - if (!softwareClipping) batch.flush(); - clipEnd(); - } + if (clipper.isClipping() && clipper.getClippingAttachment().getEndSlot() == i) clipper.clipEnd(); } } @@ -269,7 +237,7 @@ public class SkeletonRenderer implements Disposable { float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a; Array drawOrder = skeleton.drawOrder; for (int i = 0, n = drawOrder.size; i < n; i++) { - final int vertexSize = (softwareClipping && clipAttachment != null) ? 2 : 6; + final int vertexSize = clipper.isClipping() ? 2 : 6; Slot slot = drawOrder.get(i); Attachment attachment = slot.attachment; if (attachment instanceof RegionAttachment) { @@ -295,9 +263,7 @@ public class SkeletonRenderer implements Disposable { } else if (attachment instanceof ClippingAttachment) { ClippingAttachment clip = (ClippingAttachment)attachment; - if (!softwareClipping) batch.end(); - clipStart(batch.getProjectionMatrix(), batch.getTransformMatrix(), slot, clip); - if (!softwareClipping) batch.begin(); + clipper.clipStart(slot, clip); continue; } else if (attachment instanceof SkeletonAttachment) { @@ -346,21 +312,12 @@ public class SkeletonRenderer implements Disposable { batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); } - if (softwareClipping) { - if (clipAttachment != null) { - 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); - } 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); - } + if (clipper.isClipping()) { + clipper.clipTriangles(vertices, verticesLength, triangles, triangles.length, uvs, dark, light, true); + FloatArray clippedVertices = clipper.getClippedVertices(); + ShortArray clippedTriangles = clipper.getClippedTriangles(); + batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, + clippedTriangles.size); } else { for (int v = 2, u = 0; v < verticesLength; v += 6, u += 2) { vertices[v] = light; @@ -372,189 +329,7 @@ public class SkeletonRenderer implements Disposable { } } - if (clipAttachment != null && i == clipAttachment.getEndSlot()) { - if (!softwareClipping) batch.flush(); - clipEnd(); - } - } - } - - private void clipStart (Matrix4 transformMatrix, Matrix4 projectionMatrix, Slot slot, ClippingAttachment clip) { - if (clipAttachment != null) return; - clipAttachment = clip; - - if (!softwareClipping) { - int n = clip.getWorldVerticesLength(); - float[] vertices = this.vertices.setSize(n); - clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); - - Gdx.gl.glClearStencil(0); - Gdx.gl.glClear(GL20.GL_STENCIL_BUFFER_BIT); - Gdx.gl.glEnable(GL20.GL_STENCIL_TEST); - Gdx.gl.glStencilFunc(GL20.GL_NEVER, 0, 1); - Gdx.gl.glStencilOp(GL20.GL_INVERT, GL20.GL_INVERT, GL20.GL_INVERT); - Gdx.gl.glColorMask(false, false, false, false); - - if (renderer == null || renderer.getMaxVertices() < n) - renderer = new ImmediateModeRenderer20(Math.max(100, n), false, false, 0); - renderer.begin(combinedMatrix.set(projectionMatrix).mul(transformMatrix), GL20.GL_TRIANGLE_FAN); - renderer.vertex(vertices[0], vertices[1], 0); - for (int i = 2; i < n; i += 2) - renderer.vertex(vertices[i], vertices[i + 1], 0); - renderer.end(); - - Gdx.gl.glColorMask(true, true, true, true); - Gdx.gl.glStencilFunc(false ? GL20.GL_NOTEQUAL : GL20.GL_EQUAL, 1, 1); - Gdx.gl.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP); - } else { - int n = clip.getWorldVerticesLength(); - float[] vertices = this.clippingPolygon.setSize(n); - clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); - convexClippingPolygons = decomposer.decompose(clippingPolygon); - for (FloatArray poly: convexClippingPolygons) { - Clipper.makeClockwise(poly); - poly.add(poly.items[0]); - poly.add(poly.items[1]); - } - } - } - - private void clipEnd() { - clippedVertices.clear(); - clippedTriangles.clear(); - clippingPolygon.clear(); - convexClippingPolygons = null; - clipAttachment = null; - 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 float uvs[], final float dark, final float light, - final boolean twoColor, final FloatArray clippedVertices, final ShortArray clippedTriangles) { - short idx = 0; - clippedVertices.clear(); - clippedTriangles.clear(); - for (FloatArray convexClippingPolygon: convexClippingPolygons) { - for (int i = 0; i < trianglesLength; i += 3) { - int vertexOffset = triangles[i] << 1; - float x1 = vertices[vertexOffset]; - float y1= vertices[vertexOffset + 1]; - float u1 = uvs[vertexOffset]; - float v1 = uvs[vertexOffset + 1]; - - vertexOffset = triangles[i + 1] << 1; - float x2 = vertices[vertexOffset]; - float y2 = vertices[vertexOffset + 1]; - float u2 = uvs[vertexOffset]; - float v2 = uvs[vertexOffset + 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, convexClippingPolygon, clipOutput); - if (clipped) { - if (clipOutput.size == 0) continue; - float d0 = y2 - y3; - float d1 = x3 - x2; - float d2 = x1 - x3; - float d3 = y1 - y3; - float d4 = y3 - y1; - - float denom = 1 / (d0 * d2 + d1 * d3); - - 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) { - float x = clipVertices[j]; - float y = clipVertices[j + 1]; - - float c0 = x - x3; - float c1 = y - y3; - float a = (d0 * c0 + d1 * c1) * denom; - float b = (d4 * c0 + d2 * c1) * denom; - float c = 1.0f - a - b; - - float u = u1 * a + u2 * b + u3 * c; - float v = v1 * a + v2 * b + v3 * c; - 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++) { - clippedTrianglesArray[s++] = idx; - clippedTrianglesArray[s++] = (short)(idx + j); - clippedTrianglesArray[s++] = (short)(idx + j + 1); - } - - idx += clipOutput.size >> 1; - } else { - int s = clippedVertices.size; - clippedVertices.setSize(s + 3 * (twoColor ? 6 : 5)); - final float[] clippedVerticesArray = clippedVertices.items; - - 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; - } - - s = clippedTriangles.size; - clippedTriangles.setSize(s + 3); - final short[] clippedTrianglesArray = clippedTriangles.items; - clippedTrianglesArray[s] = idx++; - clippedTrianglesArray[s + 1] = idx++; - clippedTrianglesArray[s + 2] = idx++; - } - } + if (clipper.isClipping() && clipper.getClippingAttachment().getEndSlot() == i) clipper.clipEnd(); } } @@ -565,12 +340,4 @@ public class SkeletonRenderer implements Disposable { public void dispose () { renderer.dispose(); } - - public boolean getSoftwareClipping () { - return softwareClipping; - } - - public void setSoftwareClipping (boolean softwareClipping) { - this.softwareClipping = softwareClipping; - } -} +} \ No newline at end of file