mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 09:16:01 +08:00
[c] Added stride to spSkeletonClipping_clipTriangles. [cocos2dx] Added clipping.
This commit is contained in:
parent
e185e7f310
commit
676b740269
@ -27,6 +27,7 @@
|
||||
* Removed `sp_MeshAttachment_computeWorldVertices`, superseded by `spVertexAttachment_computeWorldVertices`.
|
||||
* Removed `spBone_worldToLocalRotationX` and `spBone_worldToLocalRotationY`. Replaced by `spBone_worldToLocalRotation` (rotation given relative to x-axis, counter-clockwise, in degrees).
|
||||
* Replaced `r`, `g`, `b`, `a` fields with instances of new `spColor` struct in `spRegionAttachment`, `spMeshAttachment`, `spSkeleton`, `spSkeletonData`, `spSlot` and `spSlotData`.
|
||||
* Removed `spVertexIndex`from public API.
|
||||
* **Additions**
|
||||
* Added support for local and relative transform constraint calculation, including additional fields in `spTransformConstraintData`.
|
||||
* Added `spPointAttachment`, additional method `spAtlasAttachmentLoadeR_newPointAttachment`.
|
||||
@ -42,10 +43,12 @@
|
||||
* Added support for two color tinting. Tinting is enabled/disabled per `SkeletonRenderer`/`SkeletonAnimation` instance. Use `SkeletonRenderer::setTwoColorTint()`. Note that two color tinting requires the use of a non-standard shader and vertex format. This means that skeletons rendered with two color tinting will break batching. However, skeletons with two color tinting enabled and rendered after each other will be batched.
|
||||
* Updated example to use Cocos2d-x 3.14.1.
|
||||
* Added mesh debug rendering. Enable/Disable via `SkeletonRenderer::setDebugMeshesEnabled()`.
|
||||
* Added support for clipping.
|
||||
|
||||
### Cocos2d-Objc
|
||||
* Fixed renderer to work with 3.6 changes
|
||||
* Added support for two color tinting. Tinting is enabled/disabled per `SkeletonRenderer/SkeletonAnimation.twoColorTint = true`. Note that two color tinted skeletons do not batch with other nodes.
|
||||
* Added support for clipping.
|
||||
|
||||
### SFML
|
||||
* Fixed renderer to work with 3.6 changes. Sadly, two color tinting does not work, as the vertex format in SFML is fixed.
|
||||
@ -53,6 +56,7 @@
|
||||
### Unreal Engine 4
|
||||
* Fixed renderer to work with 3.6 changes
|
||||
* Added new UPROPERTY to SpineSkeletonRendererComponent called `Color`. This allows to set the tint color of the skeleton in the editor, C++ and Blueprints. Under the hood, the `spSkeleton->color` will be set on every tick of the renderer component.
|
||||
* Added support for clipping.
|
||||
|
||||
## C#
|
||||
* **Breaking changes**
|
||||
|
||||
@ -39,10 +39,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SP_VERTEX_X1 = 0, SP_VERTEX_Y1, SP_VERTEX_X2, SP_VERTEX_Y2, SP_VERTEX_X3, SP_VERTEX_Y3, SP_VERTEX_X4, SP_VERTEX_Y4
|
||||
} spVertexIndex;
|
||||
|
||||
typedef struct spRegionAttachment {
|
||||
spAttachment super;
|
||||
const char* path;
|
||||
@ -64,15 +60,6 @@ void spRegionAttachment_updateOffset (spRegionAttachment* self);
|
||||
void spRegionAttachment_computeWorldVertices (spRegionAttachment* self, spBone* bone, float* vertices, int offset, int stride);
|
||||
|
||||
#ifdef SPINE_SHORT_NAMES
|
||||
typedef spVertexIndex VertexIndex;
|
||||
#define VERTEX_X1 SP_VERTEX_X1
|
||||
#define VERTEX_Y1 SP_VERTEX_Y1
|
||||
#define VERTEX_X2 SP_VERTEX_X2
|
||||
#define VERTEX_Y2 SP_VERTEX_Y2
|
||||
#define VERTEX_X3 SP_VERTEX_X3
|
||||
#define VERTEX_Y3 SP_VERTEX_Y3
|
||||
#define VERTEX_X4 SP_VERTEX_X4
|
||||
#define VERTEX_Y4 SP_VERTEX_Y4
|
||||
typedef spRegionAttachment RegionAttachment;
|
||||
#define RegionAttachment_create(...) spRegionAttachment_create(__VA_ARGS__)
|
||||
#define RegionAttachment_setUVs(...) spRegionAttachment_setUVs(__VA_ARGS__)
|
||||
|
||||
@ -57,7 +57,7 @@ int spSkeletonClipping_clipStart(spSkeletonClipping* self, spSlot* slot, spClipp
|
||||
void spSkeletonClipping_clipEnd(spSkeletonClipping* self, spSlot* slot);
|
||||
void spSkeletonClipping_clipEnd2(spSkeletonClipping* self);
|
||||
int /*boolean*/ spSkeletonClipping_isClipping(spSkeletonClipping* self);
|
||||
void spSkeletonClipping_clipTriangles(spSkeletonClipping* self, float* vertices, int verticesLength, unsigned short* triangles, int trianglesLength, float* uvs);
|
||||
void spSkeletonClipping_clipTriangles(spSkeletonClipping* self, float* vertices, int verticesLength, unsigned short* triangles, int trianglesLength, float* uvs, int stride);
|
||||
void spSkeletonClipping_dispose(spSkeletonClipping* self);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -31,6 +31,10 @@
|
||||
#include <spine/RegionAttachment.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
typedef enum {
|
||||
BLX = 0, BLY, ULX, ULY, URX, URY, BRX, BRY
|
||||
} spVertexIndex;
|
||||
|
||||
void _spRegionAttachment_dispose (spAttachment* attachment) {
|
||||
spRegionAttachment* self = SUB_CAST(spRegionAttachment, attachment);
|
||||
_spAttachment_deinit(attachment);
|
||||
@ -49,23 +53,23 @@ spRegionAttachment* spRegionAttachment_create (const char* name) {
|
||||
|
||||
void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate) {
|
||||
if (rotate) {
|
||||
self->uvs[SP_VERTEX_X2] = u;
|
||||
self->uvs[SP_VERTEX_Y2] = v2;
|
||||
self->uvs[SP_VERTEX_X3] = u;
|
||||
self->uvs[SP_VERTEX_Y3] = v;
|
||||
self->uvs[SP_VERTEX_X4] = u2;
|
||||
self->uvs[SP_VERTEX_Y4] = v;
|
||||
self->uvs[SP_VERTEX_X1] = u2;
|
||||
self->uvs[SP_VERTEX_Y1] = v2;
|
||||
self->uvs[URX] = u;
|
||||
self->uvs[URY] = v2;
|
||||
self->uvs[BRX] = u;
|
||||
self->uvs[BRY] = v;
|
||||
self->uvs[BLX] = u2;
|
||||
self->uvs[BLY] = v;
|
||||
self->uvs[ULX] = u2;
|
||||
self->uvs[ULY] = v2;
|
||||
} else {
|
||||
self->uvs[SP_VERTEX_X1] = u;
|
||||
self->uvs[SP_VERTEX_Y1] = v2;
|
||||
self->uvs[SP_VERTEX_X2] = u;
|
||||
self->uvs[SP_VERTEX_Y2] = v;
|
||||
self->uvs[SP_VERTEX_X3] = u2;
|
||||
self->uvs[SP_VERTEX_Y3] = v;
|
||||
self->uvs[SP_VERTEX_X4] = u2;
|
||||
self->uvs[SP_VERTEX_Y4] = v2;
|
||||
self->uvs[ULX] = u;
|
||||
self->uvs[ULY] = v2;
|
||||
self->uvs[URX] = u;
|
||||
self->uvs[URY] = v;
|
||||
self->uvs[BRX] = u2;
|
||||
self->uvs[BRY] = v;
|
||||
self->uvs[BLX] = u2;
|
||||
self->uvs[BLY] = v2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,32 +90,41 @@ void spRegionAttachment_updateOffset (spRegionAttachment* self) {
|
||||
float localX2Sin = localX2 * sine;
|
||||
float localY2Cos = localY2 * cosine + self->y;
|
||||
float localY2Sin = localY2 * sine;
|
||||
self->offset[SP_VERTEX_X1] = localXCos - localYSin;
|
||||
self->offset[SP_VERTEX_Y1] = localYCos + localXSin;
|
||||
self->offset[SP_VERTEX_X2] = localXCos - localY2Sin;
|
||||
self->offset[SP_VERTEX_Y2] = localY2Cos + localXSin;
|
||||
self->offset[SP_VERTEX_X3] = localX2Cos - localY2Sin;
|
||||
self->offset[SP_VERTEX_Y3] = localY2Cos + localX2Sin;
|
||||
self->offset[SP_VERTEX_X4] = localX2Cos - localYSin;
|
||||
self->offset[SP_VERTEX_Y4] = localYCos + localX2Sin;
|
||||
self->offset[BLX] = localXCos - localYSin;
|
||||
self->offset[BLY] = localYCos + localXSin;
|
||||
self->offset[ULX] = localXCos - localY2Sin;
|
||||
self->offset[ULY] = localY2Cos + localXSin;
|
||||
self->offset[URX] = localX2Cos - localY2Sin;
|
||||
self->offset[URY] = localY2Cos + localX2Sin;
|
||||
self->offset[BRX] = localX2Cos - localYSin;
|
||||
self->offset[BRY] = localYCos + localX2Sin;
|
||||
}
|
||||
|
||||
void spRegionAttachment_computeWorldVertices (spRegionAttachment* self, spBone* bone, float* vertices, int offset, int stride) {
|
||||
const float* offsets = self->offset;
|
||||
float x = bone->worldX, y = bone->worldY;
|
||||
float offsetX, offsetY;
|
||||
|
||||
vertices[offset] = offsets[SP_VERTEX_X1] * bone->a + offsets[SP_VERTEX_Y1] * bone->b + x; /* br */
|
||||
vertices[offset + 1] = offsets[SP_VERTEX_X1] * bone->c + offsets[SP_VERTEX_Y1] * bone->d + y;
|
||||
offsetX = offsets[BRX];
|
||||
offsetY = offsets[BRY];
|
||||
vertices[offset] = offsetX * bone->a + offsetY * bone->b + x; /* br */
|
||||
vertices[offset + 1] = offsetX * bone->c + offsetY * bone->d + y;
|
||||
offset += stride;
|
||||
|
||||
vertices[offset] = offsets[SP_VERTEX_X2] * bone->a + offsets[SP_VERTEX_Y2] * bone->b + x; /* bl */
|
||||
vertices[offset + 1] = offsets[SP_VERTEX_X2] * bone->c + offsets[SP_VERTEX_Y2] * bone->d + y;
|
||||
offsetX = offsets[BLX];
|
||||
offsetY = offsets[BLY];
|
||||
vertices[offset] = offsetX * bone->a + offsetY * bone->b + x; /* bl */
|
||||
vertices[offset + 1] = offsetX * bone->c + offsetY * bone->d + y;
|
||||
offset += stride;
|
||||
|
||||
vertices[offset] = offsets[SP_VERTEX_X3] * bone->a + offsets[SP_VERTEX_Y3] * bone->b + x; /* ul */
|
||||
vertices[offset + 1] = offsets[SP_VERTEX_X3] * bone->c + offsets[SP_VERTEX_Y3] * bone->d + y;
|
||||
offsetX = offsets[ULX];
|
||||
offsetY = offsets[ULY];
|
||||
vertices[offset] = offsetX * bone->a + offsetY * bone->b + x; /* ul */
|
||||
vertices[offset + 1] = offsetX * bone->c + offsetY * bone->d + y;
|
||||
offset += stride;
|
||||
|
||||
vertices[offset] = offsets[SP_VERTEX_X4] * bone->a + offsets[SP_VERTEX_Y4] * bone->b + x; /* ur */
|
||||
vertices[offset + 1] = offsets[SP_VERTEX_X4] * bone->c + offsets[SP_VERTEX_Y4] * bone->d + y;
|
||||
offsetX = offsets[URX];
|
||||
offsetY = offsets[URY];
|
||||
vertices[offset] = offsetX * bone->a + offsetY * bone->b + x; /* ur */
|
||||
vertices[offset + 1] = offsetX * bone->c + offsetY * bone->d + y;
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ int /*boolean*/ _clip(spSkeletonClipping* self, float x1, float y1, float x2, fl
|
||||
return clipped;
|
||||
}
|
||||
|
||||
void spSkeletonClipping_clipTriangles(spSkeletonClipping* self, float* vertices, int verticesLength, unsigned short* triangles, int trianglesLength, float* uvs) {
|
||||
void spSkeletonClipping_clipTriangles(spSkeletonClipping* self, float* vertices, int verticesLength, unsigned short* triangles, int trianglesLength, float* uvs, int stride) {
|
||||
int i;
|
||||
spFloatArray* clipOutput = self->clipOutput;
|
||||
spFloatArray* clippedVertices = self->clippedVertices;
|
||||
@ -214,7 +214,6 @@ void spSkeletonClipping_clipTriangles(spSkeletonClipping* self, float* vertices,
|
||||
spUnsignedShortArray* clippedTriangles = self->clippedTriangles;
|
||||
spFloatArray** polygons = self->clippingPolygons->items;
|
||||
int polygonsCount = self->clippingPolygons->size;
|
||||
int vertexSize = 2;
|
||||
|
||||
short index = 0;
|
||||
spFloatArray_clear(clippedVertices);
|
||||
@ -223,16 +222,16 @@ void spSkeletonClipping_clipTriangles(spSkeletonClipping* self, float* vertices,
|
||||
outer:
|
||||
for (i = 0; i < trianglesLength; i += 3) {
|
||||
int p;
|
||||
int vertexOffset = triangles[i] << 1;
|
||||
int vertexOffset = triangles[i] * stride;
|
||||
float x2, y2, u2, v2, x3, y3, u3, v3;
|
||||
float x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
|
||||
float u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
|
||||
|
||||
vertexOffset = triangles[i + 1] << 1;
|
||||
vertexOffset = triangles[i + 1] * stride;
|
||||
x2 = vertices[vertexOffset]; y2 = vertices[vertexOffset + 1];
|
||||
u2 = uvs[vertexOffset]; v2 = uvs[vertexOffset + 1];
|
||||
|
||||
vertexOffset = triangles[i + 2] << 1;
|
||||
vertexOffset = triangles[i + 2] * stride;
|
||||
x3 = vertices[vertexOffset]; y3 = vertices[vertexOffset + 1];
|
||||
u3 = uvs[vertexOffset]; v3 = uvs[vertexOffset + 1];
|
||||
|
||||
@ -254,8 +253,8 @@ void spSkeletonClipping_clipTriangles(spSkeletonClipping* self, float* vertices,
|
||||
|
||||
clipOutputCount = clipOutputLength >> 1;
|
||||
clipOutputItems = clipOutput->items;
|
||||
clippedVerticesItems = spFloatArray_setSize(clippedVertices, s + clipOutputCount * vertexSize)->items;
|
||||
clippedUVsItems = spFloatArray_setSize(clippedUVs, s + clipOutputCount * vertexSize)->items;
|
||||
clippedVerticesItems = spFloatArray_setSize(clippedVertices, s + (clipOutputCount << 1))->items;
|
||||
clippedUVsItems = spFloatArray_setSize(clippedUVs, s + (clipOutputCount << 1))->items;
|
||||
for (ii = 0; ii < clipOutputLength; ii += 2) {
|
||||
float c0, c1, a, b, c;
|
||||
float x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
|
||||
@ -283,8 +282,8 @@ void spSkeletonClipping_clipTriangles(spSkeletonClipping* self, float* vertices,
|
||||
|
||||
} else {
|
||||
unsigned short* clippedTrianglesItems;
|
||||
float* clippedVerticesItems = spFloatArray_setSize(clippedVertices, s + 3 * vertexSize)->items;
|
||||
float* clippedUVsItems = spFloatArray_setSize(clippedUVs, s + 3 * vertexSize)->items;
|
||||
float* clippedVerticesItems = spFloatArray_setSize(clippedVertices, s + (3 << 1))->items;
|
||||
float* clippedUVsItems = spFloatArray_setSize(clippedUVs, s + (3 << 1))->items;
|
||||
clippedVerticesItems[s] = x1;
|
||||
clippedVerticesItems[s + 1] = y1;
|
||||
clippedVerticesItems[s + 2] = x2;
|
||||
|
||||
@ -272,7 +272,7 @@ static bool handlerQueued = false;
|
||||
if (_skipVisibilityCheck || CCRenderCheckVisbility(transform, center, extents)) {
|
||||
|
||||
if (spSkeletonClipping_isClipping(_clipper)) {
|
||||
spSkeletonClipping_clipTriangles(_clipper, vertices, verticesCount, triangles, trianglesCount, uvs);
|
||||
spSkeletonClipping_clipTriangles(_clipper, vertices, verticesCount, triangles, trianglesCount, uvs, 2);
|
||||
vertices = _clipper->clippedVertices->items;
|
||||
verticesCount = _clipper->clippedVertices->size;
|
||||
uvs = _clipper->clippedUVs->items;
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
|
||||
#include "RaptorExample.h"
|
||||
#include "BatchingExample.h"
|
||||
#include "CoinExample.h"
|
||||
#include "AppMacros.h"
|
||||
|
||||
USING_NS_CC;
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
USING_NS_CC;
|
||||
using namespace spine;
|
||||
|
||||
#define NUM_SKELETONS 50
|
||||
|
||||
Scene* BatchingExample::scene () {
|
||||
Scene *scene = Scene::create();
|
||||
scene->addChild(BatchingExample::create());
|
||||
@ -65,7 +67,7 @@ bool BatchingExample::init () {
|
||||
|
||||
int xMin = _contentSize.width * 0.10f, xMax = _contentSize.width * 0.90f;
|
||||
int yMin = 0, yMax = _contentSize.height * 0.7f;
|
||||
for (int i = 0, j = 0; i < 50; i++) {
|
||||
for (int i = 0, j = 0; i < NUM_SKELETONS; i++) {
|
||||
// Each skeleton node shares the same atlas, skeleton data, and mix times.
|
||||
SkeletonAnimation* skeletonNode = SkeletonAnimation::createWithData(_skeletonData, false);
|
||||
skeletonNode->setAnimationStateData(_stateData);
|
||||
@ -76,9 +78,10 @@ bool BatchingExample::init () {
|
||||
|
||||
// alternative setting two color tint for groups of 10 skeletons
|
||||
// should end up with #skeletons / 10 batches
|
||||
if (j++ < 10)
|
||||
skeletonNode->setTwoColorTint(true);
|
||||
if (j == 20) j = 0;
|
||||
// if (j++ < 10)
|
||||
// skeletonNode->setTwoColorTint(true);
|
||||
// if (j == 20) j = 0;
|
||||
// skeletonNode->setTwoColorTint(true);
|
||||
|
||||
skeletonNode->setPosition(Vec2(
|
||||
RandomHelper::random_int(xMin, xMax),
|
||||
|
||||
@ -43,10 +43,10 @@ Scene* CoinExample::scene () {
|
||||
bool CoinExample::init () {
|
||||
if (!LayerColor::initWithColor(Color4B(128, 128, 128, 255))) return false;
|
||||
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("coin.json", "coin.atlas", 0.5f);
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("coin.json", "coin.atlas", 1);
|
||||
skeletonNode->setAnimation(0, "rotate", true);
|
||||
|
||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 150));
|
||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 100));
|
||||
addChild(skeletonNode);
|
||||
|
||||
scheduleUpdate();
|
||||
|
||||
@ -58,6 +58,8 @@ SkeletonBatch::SkeletonBatch () {
|
||||
_commandsPool.push_back(new TrianglesCommand());
|
||||
}
|
||||
|
||||
_indices = spUnsignedShortArray_create(8);
|
||||
|
||||
reset ();
|
||||
|
||||
// callback after drawing is finished so we can clear out the batch state
|
||||
@ -70,6 +72,8 @@ SkeletonBatch::SkeletonBatch () {
|
||||
SkeletonBatch::~SkeletonBatch () {
|
||||
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
||||
|
||||
spUnsignedShortArray_dispose(_indices);
|
||||
|
||||
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
||||
delete _commandsPool[i];
|
||||
_commandsPool[i] = nullptr;
|
||||
@ -97,6 +101,36 @@ cocos2d::V3F_C4B_T2F* SkeletonBatch::allocateVertices(uint32_t numVertices) {
|
||||
return vertices;
|
||||
}
|
||||
|
||||
void SkeletonBatch::deallocateVertices(uint32_t numVertices) {
|
||||
_numVertices -= numVertices;
|
||||
}
|
||||
|
||||
|
||||
unsigned short* SkeletonBatch::allocateIndices(uint32_t numIndices) {
|
||||
if (_indices->capacity - _indices->size < numIndices) {
|
||||
unsigned short* oldData = _indices->items;
|
||||
int oldSize = _indices->size;
|
||||
spUnsignedShortArray_ensureCapacity(_indices, _indices->size + numIndices);
|
||||
unsigned short* newData = _indices->items;
|
||||
for (uint32_t i = 0; i < this->_nextFreeCommand; i++) {
|
||||
TrianglesCommand* command = _commandsPool[i];
|
||||
cocos2d::TrianglesCommand::Triangles& triangles = (cocos2d::TrianglesCommand::Triangles&)command->getTriangles();
|
||||
if (triangles.indices >= oldData && triangles.indices < oldData + oldSize) {
|
||||
triangles.indices = newData + (triangles.indices - oldData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short* indices = _indices->items + _indices->size;
|
||||
_indices->size += numIndices;
|
||||
return indices;
|
||||
}
|
||||
|
||||
void SkeletonBatch::deallocateIndices(uint32_t numIndices) {
|
||||
_indices->size -= numIndices;
|
||||
}
|
||||
|
||||
|
||||
cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
||||
TrianglesCommand* command = nextFreeCommand();
|
||||
command->init(globalOrder, texture, glProgramState, blendType, triangles, mv, flags);
|
||||
@ -107,6 +141,7 @@ cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer
|
||||
void SkeletonBatch::reset() {
|
||||
_nextFreeCommand = 0;
|
||||
_numVertices = 0;
|
||||
_indices->size = 0;
|
||||
}
|
||||
|
||||
cocos2d::TrianglesCommand* SkeletonBatch::nextFreeCommand() {
|
||||
|
||||
@ -46,6 +46,9 @@ namespace spine {
|
||||
void update (float delta);
|
||||
|
||||
cocos2d::V3F_C4B_T2F* allocateVertices(uint32_t numVertices);
|
||||
void deallocateVertices(uint32_t numVertices);
|
||||
unsigned short* allocateIndices(uint32_t numIndices);
|
||||
void deallocateIndices(uint32_t numVertices);
|
||||
cocos2d::TrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
||||
|
||||
protected:
|
||||
@ -63,6 +66,9 @@ namespace spine {
|
||||
// pool of vertices
|
||||
std::vector<cocos2d::V3F_C4B_T2F> _vertices;
|
||||
uint32_t _numVertices;
|
||||
|
||||
// pool of indices
|
||||
spUnsignedShortArray* _indices;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -229,15 +229,6 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
|
||||
color.b = attachment->color.b;
|
||||
color.a = attachment->color.a;
|
||||
|
||||
if (slot->darkColor) {
|
||||
darkColor.r = slot->darkColor->r * 255;
|
||||
darkColor.g = slot->darkColor->g * 255;
|
||||
darkColor.b = slot->darkColor->b * 255;
|
||||
} else {
|
||||
darkColor.r = 0;
|
||||
darkColor.g = 0;
|
||||
darkColor.b = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SP_ATTACHMENT_MESH: {
|
||||
@ -267,15 +258,6 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
|
||||
color.b = attachment->color.b;
|
||||
color.a = attachment->color.a;
|
||||
|
||||
if (slot->darkColor) {
|
||||
darkColor.r = slot->darkColor->r * 255;
|
||||
darkColor.g = slot->darkColor->g * 255;
|
||||
darkColor.b = slot->darkColor->b * 255;
|
||||
} else {
|
||||
darkColor.r = 0;
|
||||
darkColor.g = 0;
|
||||
darkColor.b = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SP_ATTACHMENT_CLIPPING: {
|
||||
@ -286,6 +268,16 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
|
||||
continue;
|
||||
}
|
||||
|
||||
if (slot->darkColor) {
|
||||
darkColor.r = slot->darkColor->r * 255;
|
||||
darkColor.g = slot->darkColor->g * 255;
|
||||
darkColor.b = slot->darkColor->b * 255;
|
||||
} else {
|
||||
darkColor.r = 0;
|
||||
darkColor.g = 0;
|
||||
darkColor.b = 0;
|
||||
}
|
||||
|
||||
color.a *= _skeleton->color.a * slot->color.a * 255;
|
||||
float multiplier = _premultipliedAlpha ? color.a : 255;
|
||||
color.r *= _skeleton->color.r * slot->color.r * multiplier;
|
||||
@ -312,6 +304,35 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
|
||||
}
|
||||
|
||||
if (!isTwoColorTint) {
|
||||
if (spSkeletonClipping_isClipping(_clipper)) {
|
||||
spSkeletonClipping_clipTriangles(_clipper, (float*)&triangles.verts[0].vertices, triangles.vertCount * sizeof(cocos2d::V3F_C4B_T2F) / 4, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoords, 6);
|
||||
batch->deallocateVertices(triangles.vertCount);
|
||||
|
||||
if (_clipper->clippedTriangles->size == 0)
|
||||
continue;
|
||||
|
||||
triangles.vertCount = _clipper->clippedVertices->size >> 1;
|
||||
triangles.verts = batch->allocateVertices(triangles.vertCount);
|
||||
triangles.indexCount = _clipper->clippedTriangles->size;
|
||||
triangles.indices = batch->allocateIndices(triangles.indexCount);
|
||||
memcpy(triangles.indices, _clipper->clippedTriangles->items, sizeof(unsigned short) * _clipper->clippedTriangles->size);
|
||||
|
||||
cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags);
|
||||
|
||||
float* verts = _clipper->clippedVertices->items;
|
||||
float* uvs = _clipper->clippedUVs->items;
|
||||
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv+=2) {
|
||||
V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
|
||||
vertex->vertices.x = verts[vv];
|
||||
vertex->vertices.y = verts[vv + 1];
|
||||
vertex->texCoords.u = uvs[vv];
|
||||
vertex->texCoords.v = uvs[vv + 1];
|
||||
vertex->colors.r = (GLubyte)color.r;
|
||||
vertex->colors.g = (GLubyte)color.g;
|
||||
vertex->colors.b = (GLubyte)color.b;
|
||||
vertex->colors.a = (GLubyte)color.a;
|
||||
}
|
||||
} else {
|
||||
cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags);
|
||||
|
||||
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
|
||||
@ -321,6 +342,40 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
|
||||
vertex->colors.b = (GLubyte)color.b;
|
||||
vertex->colors.a = (GLubyte)color.a;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (spSkeletonClipping_isClipping(_clipper)) {
|
||||
spSkeletonClipping_clipTriangles(_clipper, (float*)&trianglesTwoColor.verts[0].position, trianglesTwoColor.vertCount * sizeof(V3F_C4B_C4B_T2F) / 4, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoords, 7);
|
||||
twoColorBatch->deallocateVertices(trianglesTwoColor.vertCount);
|
||||
|
||||
if (_clipper->clippedTriangles->size == 0)
|
||||
continue;
|
||||
|
||||
trianglesTwoColor.vertCount = _clipper->clippedVertices->size >> 1;
|
||||
trianglesTwoColor.verts = twoColorBatch->allocateVertices(trianglesTwoColor.vertCount);
|
||||
trianglesTwoColor.indexCount = _clipper->clippedTriangles->size;
|
||||
trianglesTwoColor.indices = twoColorBatch->allocateIndices(trianglesTwoColor.indexCount);
|
||||
memcpy(trianglesTwoColor.indices, _clipper->clippedTriangles->items, sizeof(unsigned short) * _clipper->clippedTriangles->size);
|
||||
|
||||
TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags);
|
||||
|
||||
float* verts = _clipper->clippedVertices->items;
|
||||
float* uvs = _clipper->clippedUVs->items;
|
||||
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) {
|
||||
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
|
||||
vertex->position.x = verts[vv];
|
||||
vertex->position.y = verts[vv + 1];
|
||||
vertex->texCoords.u = uvs[vv];
|
||||
vertex->texCoords.v = uvs[vv + 1];
|
||||
vertex->color.r = (GLubyte)color.r;
|
||||
vertex->color.g = (GLubyte)color.g;
|
||||
vertex->color.b = (GLubyte)color.b;
|
||||
vertex->color.a = (GLubyte)color.a;
|
||||
vertex->color2.r = (GLubyte)darkColor.r;
|
||||
vertex->color2.g = (GLubyte)darkColor.g;
|
||||
vertex->color2.b = (GLubyte)darkColor.b;
|
||||
vertex->color2.a = 1;
|
||||
}
|
||||
} else {
|
||||
TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags);
|
||||
|
||||
@ -336,6 +391,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
|
||||
vertex->color2.a = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
spSkeletonClipping_clipEnd(_clipper, slot);
|
||||
}
|
||||
spSkeletonClipping_clipEnd2(_clipper);
|
||||
|
||||
@ -168,6 +168,8 @@ SkeletonTwoColorBatch::SkeletonTwoColorBatch () {
|
||||
_commandsPool.push_back(new TwoColorTrianglesCommand());
|
||||
}
|
||||
|
||||
_indices = spUnsignedShortArray_create(8);
|
||||
|
||||
reset ();
|
||||
|
||||
// callback after drawing is finished so we can clear out the batch state
|
||||
@ -193,6 +195,8 @@ SkeletonTwoColorBatch::SkeletonTwoColorBatch () {
|
||||
SkeletonTwoColorBatch::~SkeletonTwoColorBatch () {
|
||||
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
||||
|
||||
spUnsignedShortArray_dispose(_indices);
|
||||
|
||||
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
||||
delete _commandsPool[i];
|
||||
_commandsPool[i] = nullptr;
|
||||
@ -223,6 +227,36 @@ V3F_C4B_C4B_T2F* SkeletonTwoColorBatch::allocateVertices(uint32_t numVertices) {
|
||||
return vertices;
|
||||
}
|
||||
|
||||
|
||||
void SkeletonTwoColorBatch::deallocateVertices(uint32_t numVertices) {
|
||||
_numVertices -= numVertices;
|
||||
}
|
||||
|
||||
|
||||
unsigned short* SkeletonTwoColorBatch::allocateIndices(uint32_t numIndices) {
|
||||
if (_indices->capacity - _indices->size < numIndices) {
|
||||
unsigned short* oldData = _indices->items;
|
||||
int oldSize =_indices->size;
|
||||
spUnsignedShortArray_ensureCapacity(_indices, _indices->size + numIndices);
|
||||
unsigned short* newData = _indices->items;
|
||||
for (uint32_t i = 0; i < this->_nextFreeCommand; i++) {
|
||||
TwoColorTrianglesCommand* command = _commandsPool[i];
|
||||
TwoColorTriangles& triangles = (TwoColorTriangles&)command->getTriangles();
|
||||
if (triangles.indices >= oldData && triangles.indices < oldData + oldSize) {
|
||||
triangles.indices = newData + (triangles.indices - oldData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short* indices = _indices->items + _indices->size;
|
||||
_indices->size += numIndices;
|
||||
return indices;
|
||||
}
|
||||
|
||||
void SkeletonTwoColorBatch::deallocateIndices(uint32_t numIndices) {
|
||||
_indices->size -= numIndices;
|
||||
}
|
||||
|
||||
TwoColorTrianglesCommand* SkeletonTwoColorBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
||||
TwoColorTrianglesCommand* command = nextFreeCommand();
|
||||
command->init(globalOrder, textureID, glProgramState, blendType, triangles, mv, flags);
|
||||
@ -293,6 +327,7 @@ void SkeletonTwoColorBatch::flush (TwoColorTrianglesCommand* materialCommand) {
|
||||
void SkeletonTwoColorBatch::reset() {
|
||||
_nextFreeCommand = 0;
|
||||
_numVertices = 0;
|
||||
_indices->size = 0;
|
||||
_numVerticesBuffer = 0;
|
||||
_numIndicesBuffer = 0;
|
||||
_lastCommand = nullptr;
|
||||
|
||||
@ -108,6 +108,10 @@ namespace spine {
|
||||
void update (float delta);
|
||||
|
||||
V3F_C4B_C4B_T2F* allocateVertices(uint32_t numVertices);
|
||||
void deallocateVertices(uint32_t numVertices);
|
||||
|
||||
unsigned short* allocateIndices(uint32_t numIndices);
|
||||
void deallocateIndices(uint32_t numIndices);
|
||||
|
||||
TwoColorTrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
||||
|
||||
@ -135,6 +139,9 @@ namespace spine {
|
||||
std::vector<V3F_C4B_C4B_T2F> _vertices;
|
||||
uint32_t _numVertices;
|
||||
|
||||
// pool of indices
|
||||
spUnsignedShortArray* _indices;
|
||||
|
||||
// two color tint shader and state
|
||||
cocos2d::GLProgram* _twoColorTintShader;
|
||||
cocos2d::GLProgramState* _twoColorTintShaderState;
|
||||
|
||||
@ -169,7 +169,7 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||
}
|
||||
|
||||
if (spSkeletonClipping_isClipping(clipper)) {
|
||||
spSkeletonClipping_clipTriangles(clipper, vertices, verticesCount << 1, indices, indicesCount, uvs);
|
||||
spSkeletonClipping_clipTriangles(clipper, vertices, verticesCount << 1, indices, indicesCount, uvs, 2);
|
||||
vertices = clipper->clippedVertices->items;
|
||||
verticesCount = clipper->clippedVertices->size >> 1;
|
||||
uvs = clipper->clippedUVs->items;
|
||||
|
||||
@ -264,7 +264,7 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* Skeleton) {
|
||||
}
|
||||
|
||||
if (spSkeletonClipping_isClipping(clipper)) {
|
||||
spSkeletonClipping_clipTriangles(clipper, attachmentVertices, numVertices << 1, attachmentIndices, numIndices, attachmentUvs);
|
||||
spSkeletonClipping_clipTriangles(clipper, attachmentVertices, numVertices << 1, attachmentIndices, numIndices, attachmentUvs, 2);
|
||||
attachmentVertices = clipper->clippedVertices->items;
|
||||
numVertices = clipper->clippedVertices->size >> 1;
|
||||
attachmentIndices = clipper->clippedTriangles->items;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user