2013-09-24 15:36:10 +02:00

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 */