mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-20 00:36:43 +08:00
162 lines
6.0 KiB
C++
162 lines
6.0 KiB
C++
/******************************************************************************
|
|
* Spine Runtime Software License - Version 1.0
|
|
*
|
|
* Copyright (c) 2013, Esoteric Software
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms in whole or in part, with
|
|
* or without modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. A Spine Single User License or Spine Professional License must be
|
|
* purchased from Esoteric Software and the license must remain valid:
|
|
* http://esotericsoftware.com/
|
|
* 2. Redistributions of source code must retain this license, which is the
|
|
* above copyright notice, this declaration of conditions and the following
|
|
* disclaimer.
|
|
* 3. Redistributions in binary form must reproduce this license, which is the
|
|
* above copyright notice, this declaration of conditions and the following
|
|
* disclaimer, in the documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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.
|
|
*****************************************************************************/
|
|
|
|
#include <spine/spine-sfml.h>
|
|
#include <spine/extension.h>
|
|
#include <SFML/Graphics/Vertex.hpp>
|
|
#include <SFML/Graphics/VertexArray.hpp>
|
|
#include <SFML/Graphics/Texture.hpp>
|
|
#include <SFML/Graphics/RenderTarget.hpp>
|
|
#include <SFML/Graphics/RenderStates.hpp>
|
|
|
|
using namespace sf;
|
|
|
|
void _AtlasPage_createTexture (AtlasPage* self, const char* path) {
|
|
Texture* texture = new Texture();
|
|
if (!texture->loadFromFile(path)) return;
|
|
texture->setSmooth(true);
|
|
self->rendererObject = texture;
|
|
Vector2u size = texture->getSize();
|
|
self->width = size.x;
|
|
self->height = size.y;
|
|
}
|
|
|
|
void _AtlasPage_disposeTexture (AtlasPage* self) {
|
|
delete (Texture*)self->rendererObject;
|
|
}
|
|
|
|
char* _Util_readFile (const char* path, int* length) {
|
|
return _readFile(path, length);
|
|
}
|
|
|
|
/**/
|
|
|
|
namespace spine {
|
|
|
|
SkeletonDrawable::SkeletonDrawable (SkeletonData* skeletonData, AnimationStateData* stateData) :
|
|
timeScale(1),
|
|
vertexArray(new VertexArray(Quads, skeletonData->boneCount * 4)) {
|
|
Bone_setYDown(true);
|
|
|
|
skeleton = Skeleton_create(skeletonData);
|
|
state = AnimationState_create(stateData);
|
|
}
|
|
|
|
SkeletonDrawable::~SkeletonDrawable () {
|
|
delete vertexArray;
|
|
AnimationState_dispose(state);
|
|
Skeleton_dispose(skeleton);
|
|
}
|
|
|
|
void SkeletonDrawable::update (float deltaTime) {
|
|
Skeleton_update(skeleton, deltaTime);
|
|
AnimationState_update(state, deltaTime * timeScale);
|
|
AnimationState_apply(state, skeleton);
|
|
Skeleton_updateWorldTransform(skeleton);
|
|
}
|
|
|
|
void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
|
vertexArray->clear();
|
|
states.blendMode = BlendAlpha;
|
|
|
|
float worldVertices[8];
|
|
for (int i = 0; i < skeleton->slotCount; ++i) {
|
|
Slot* slot = skeleton->drawOrder[i];
|
|
Attachment* attachment = slot->attachment;
|
|
if (!attachment || attachment->type != ATTACHMENT_REGION) continue;
|
|
RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
|
|
|
|
BlendMode blend = slot->data->additiveBlending ? BlendAdd : BlendAlpha;
|
|
if (states.blendMode != blend) {
|
|
target.draw(*vertexArray, states);
|
|
vertexArray->clear();
|
|
states.blendMode = blend;
|
|
}
|
|
|
|
RegionAttachment_computeWorldVertices(regionAttachment, slot->skeleton->x, slot->skeleton->y, slot->bone, worldVertices);
|
|
|
|
Uint8 r = skeleton->r * slot->r * 255;
|
|
Uint8 g = skeleton->g * slot->g * 255;
|
|
Uint8 b = skeleton->b * slot->b * 255;
|
|
Uint8 a = skeleton->a * slot->a * 255;
|
|
|
|
sf::Vertex vertices[4];
|
|
vertices[0].color.r = r;
|
|
vertices[0].color.g = g;
|
|
vertices[0].color.b = b;
|
|
vertices[0].color.a = a;
|
|
vertices[1].color.r = r;
|
|
vertices[1].color.g = g;
|
|
vertices[1].color.b = b;
|
|
vertices[1].color.a = a;
|
|
vertices[2].color.r = r;
|
|
vertices[2].color.g = g;
|
|
vertices[2].color.b = b;
|
|
vertices[2].color.a = a;
|
|
vertices[3].color.r = r;
|
|
vertices[3].color.g = g;
|
|
vertices[3].color.b = b;
|
|
vertices[3].color.a = a;
|
|
|
|
vertices[0].position.x = worldVertices[VERTEX_X1];
|
|
vertices[0].position.y = worldVertices[VERTEX_Y1];
|
|
vertices[1].position.x = worldVertices[VERTEX_X2];
|
|
vertices[1].position.y = worldVertices[VERTEX_Y2];
|
|
vertices[2].position.x = worldVertices[VERTEX_X3];
|
|
vertices[2].position.y = worldVertices[VERTEX_Y3];
|
|
vertices[3].position.x = worldVertices[VERTEX_X4];
|
|
vertices[3].position.y = worldVertices[VERTEX_Y4];
|
|
|
|
// SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton.
|
|
states.texture = (Texture*)((AtlasRegion*)regionAttachment->rendererObject)->page->rendererObject;
|
|
|
|
Vector2u size = states.texture->getSize();
|
|
vertices[0].texCoords.x = regionAttachment->uvs[VERTEX_X1] * size.x;
|
|
vertices[0].texCoords.y = regionAttachment->uvs[VERTEX_Y1] * size.y;
|
|
vertices[1].texCoords.x = regionAttachment->uvs[VERTEX_X2] * size.x;
|
|
vertices[1].texCoords.y = regionAttachment->uvs[VERTEX_Y2] * size.y;
|
|
vertices[2].texCoords.x = regionAttachment->uvs[VERTEX_X3] * size.x;
|
|
vertices[2].texCoords.y = regionAttachment->uvs[VERTEX_Y3] * size.y;
|
|
vertices[3].texCoords.x = regionAttachment->uvs[VERTEX_X4] * size.x;
|
|
vertices[3].texCoords.y = regionAttachment->uvs[VERTEX_Y4] * size.y;
|
|
|
|
vertexArray->append(vertices[0]);
|
|
vertexArray->append(vertices[1]);
|
|
vertexArray->append(vertices[2]);
|
|
vertexArray->append(vertices[3]);
|
|
}
|
|
target.draw(*vertexArray, states);
|
|
}
|
|
|
|
} /* namespace spine */
|