spine-sfml.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /******************************************************************************
  2. * Spine Runtimes Software License v2.5
  3. *
  4. * Copyright (c) 2013-2016, Esoteric Software
  5. * All rights reserved.
  6. *
  7. * You are granted a perpetual, non-exclusive, non-sublicensable, and
  8. * non-transferable license to use, install, execute, and perform the Spine
  9. * Runtimes software and derivative works solely for personal or internal
  10. * use. Without the written permission of Esoteric Software (see Section 2 of
  11. * the Spine Software License Agreement), you may not (a) modify, translate,
  12. * adapt, or develop new applications using the Spine Runtimes or otherwise
  13. * create derivative works or improvements of the Spine Runtimes or (b) remove,
  14. * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
  15. * or other intellectual property or proprietary rights notices on or in the
  16. * Software, including any copy thereof. Redistributions in binary or source
  17. * form must include this license and terms.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
  25. * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  26. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. *****************************************************************************/
  30. #include <spine/spine-sfml.h>
  31. #ifndef SPINE_MESH_VERTEX_COUNT_MAX
  32. #define SPINE_MESH_VERTEX_COUNT_MAX 1000
  33. #endif
  34. using namespace sf;
  35. sf::BlendMode normal = sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::OneMinusSrcAlpha);
  36. sf::BlendMode additive = sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::One);
  37. sf::BlendMode multiply = sf::BlendMode(sf::BlendMode::DstColor, sf::BlendMode::OneMinusSrcAlpha);
  38. sf::BlendMode screen = sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcColor);
  39. sf::BlendMode normalPma = sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcAlpha);
  40. sf::BlendMode additivePma = sf::BlendMode(sf::BlendMode::One, sf::BlendMode::One);
  41. sf::BlendMode multiplyPma = sf::BlendMode(sf::BlendMode::DstColor, sf::BlendMode::OneMinusSrcAlpha);
  42. sf::BlendMode screenPma = sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcColor);
  43. _SP_ARRAY_IMPLEMENT_TYPE(spColorArray, spColor)
  44. void _AtlasPage_createTexture (AtlasPage* self, const char* path){
  45. Texture* texture = new Texture();
  46. if (!texture->loadFromFile(path)) return;
  47. if (self->magFilter == SP_ATLAS_LINEAR) texture->setSmooth(true);
  48. if (self->uWrap == SP_ATLAS_REPEAT && self->vWrap == SP_ATLAS_REPEAT) texture->setRepeated(true);
  49. self->rendererObject = texture;
  50. Vector2u size = texture->getSize();
  51. self->width = size.x;
  52. self->height = size.y;
  53. }
  54. void _AtlasPage_disposeTexture (AtlasPage* self){
  55. delete (Texture*)self->rendererObject;
  56. }
  57. char* _Util_readFile (const char* path, int* length){
  58. return _spReadFile(path, length);
  59. }
  60. /**/
  61. namespace spine {
  62. SkeletonDrawable::SkeletonDrawable (SkeletonData* skeletonData, AnimationStateData* stateData) :
  63. timeScale(1),
  64. vertexArray(new VertexArray(Triangles, skeletonData->bonesCount * 4)),
  65. vertexEffect(0),
  66. worldVertices(0), clipper(0) {
  67. Bone_setYDown(true);
  68. worldVertices = MALLOC(float, SPINE_MESH_VERTEX_COUNT_MAX);
  69. skeleton = Skeleton_create(skeletonData);
  70. tempUvs = spFloatArray_create(16);
  71. tempColors = spColorArray_create(16);
  72. ownsAnimationStateData = stateData == 0;
  73. if (ownsAnimationStateData) stateData = AnimationStateData_create(skeletonData);
  74. state = AnimationState_create(stateData);
  75. clipper = spSkeletonClipping_create();
  76. }
  77. SkeletonDrawable::~SkeletonDrawable () {
  78. delete vertexArray;
  79. FREE(worldVertices);
  80. if (ownsAnimationStateData) AnimationStateData_dispose(state->data);
  81. AnimationState_dispose(state);
  82. Skeleton_dispose(skeleton);
  83. spSkeletonClipping_dispose(clipper);
  84. spFloatArray_dispose(tempUvs);
  85. spColorArray_dispose(tempColors);
  86. }
  87. void SkeletonDrawable::update (float deltaTime) {
  88. Skeleton_update(skeleton, deltaTime);
  89. AnimationState_update(state, deltaTime * timeScale);
  90. AnimationState_apply(state, skeleton);
  91. Skeleton_updateWorldTransform(skeleton);
  92. }
  93. void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
  94. vertexArray->clear();
  95. states.texture = 0;
  96. unsigned short quadIndices[6] = { 0, 1, 2, 2, 3, 0 };
  97. if (vertexEffect != 0) vertexEffect->begin(vertexEffect, skeleton);
  98. sf::Vertex vertex;
  99. Texture* texture = 0;
  100. for (int i = 0; i < skeleton->slotsCount; ++i) {
  101. Slot* slot = skeleton->drawOrder[i];
  102. Attachment* attachment = slot->attachment;
  103. if (!attachment) continue;
  104. float* vertices = worldVertices;
  105. int verticesCount = 0;
  106. float* uvs = 0;
  107. unsigned short* indices = 0;
  108. int indicesCount = 0;
  109. spColor* attachmentColor;
  110. if (attachment->type == ATTACHMENT_REGION) {
  111. RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
  112. spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, vertices, 0, 2);
  113. verticesCount = 4;
  114. uvs = regionAttachment->uvs;
  115. indices = quadIndices;
  116. indicesCount = 6;
  117. texture = (Texture*)((AtlasRegion*)regionAttachment->rendererObject)->page->rendererObject;
  118. attachmentColor = &regionAttachment->color;
  119. } else if (attachment->type == ATTACHMENT_MESH) {
  120. MeshAttachment* mesh = (MeshAttachment*)attachment;
  121. if (mesh->super.worldVerticesLength > SPINE_MESH_VERTEX_COUNT_MAX) continue;
  122. texture = (Texture*)((AtlasRegion*)mesh->rendererObject)->page->rendererObject;
  123. spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, worldVertices, 0, 2);
  124. verticesCount = mesh->super.worldVerticesLength >> 1;
  125. uvs = mesh->uvs;
  126. indices = mesh->triangles;
  127. indicesCount = mesh->trianglesCount;
  128. attachmentColor = &mesh->color;
  129. } else if (attachment->type == SP_ATTACHMENT_CLIPPING) {
  130. spClippingAttachment* clip = (spClippingAttachment*)slot->attachment;
  131. spSkeletonClipping_clipStart(clipper, slot, clip);
  132. continue;
  133. } else continue;
  134. Uint8 r = static_cast<Uint8>(skeleton->color.r * slot->color.r * attachmentColor->r * 255);
  135. Uint8 g = static_cast<Uint8>(skeleton->color.g * slot->color.g * attachmentColor->g * 255);
  136. Uint8 b = static_cast<Uint8>(skeleton->color.b * slot->color.b * attachmentColor->b * 255);
  137. Uint8 a = static_cast<Uint8>(skeleton->color.a * slot->color.a * attachmentColor->a * 255);
  138. vertex.color.r = r;
  139. vertex.color.g = g;
  140. vertex.color.b = b;
  141. vertex.color.a = a;
  142. spColor light;
  143. light.r = r / 255.0f;
  144. light.g = g / 255.0f;
  145. light.b = b / 255.0f;
  146. light.a = a / 255.0f;
  147. sf::BlendMode blend;
  148. if (!usePremultipliedAlpha) {
  149. switch (slot->data->blendMode) {
  150. case BLEND_MODE_NORMAL:
  151. blend = normal;
  152. break;
  153. case BLEND_MODE_ADDITIVE:
  154. blend = additive;
  155. break;
  156. case BLEND_MODE_MULTIPLY:
  157. blend = multiply;
  158. break;
  159. case BLEND_MODE_SCREEN:
  160. blend = screen;
  161. break;
  162. default:
  163. blend = normal;
  164. }
  165. } else {
  166. switch (slot->data->blendMode) {
  167. case BLEND_MODE_NORMAL:
  168. blend = normalPma;
  169. break;
  170. case BLEND_MODE_ADDITIVE:
  171. blend = additivePma;
  172. break;
  173. case BLEND_MODE_MULTIPLY:
  174. blend = multiplyPma;
  175. break;
  176. case BLEND_MODE_SCREEN:
  177. blend = screenPma;
  178. break;
  179. default:
  180. blend = normalPma;
  181. }
  182. }
  183. if (states.texture == 0) states.texture = texture;
  184. if (states.blendMode != blend || states.texture != texture) {
  185. target.draw(*vertexArray, states);
  186. vertexArray->clear();
  187. states.blendMode = blend;
  188. states.texture = texture;
  189. }
  190. if (spSkeletonClipping_isClipping(clipper)) {
  191. spSkeletonClipping_clipTriangles(clipper, vertices, verticesCount << 1, indices, indicesCount, uvs, 2);
  192. vertices = clipper->clippedVertices->items;
  193. verticesCount = clipper->clippedVertices->size >> 1;
  194. uvs = clipper->clippedUVs->items;
  195. indices = clipper->clippedTriangles->items;
  196. indicesCount = clipper->clippedTriangles->size;
  197. }
  198. Vector2u size = texture->getSize();
  199. if (vertexEffect != 0) {
  200. spFloatArray_clear(tempUvs);
  201. spColorArray_clear(tempColors);
  202. for (int i = 0; i < verticesCount; i++) {
  203. spColor vertexColor = light;
  204. spColor dark;
  205. dark.r = dark.g = dark.b = dark.a = 0;
  206. int index = i << 1;
  207. float x = vertices[index];
  208. float y = vertices[index + 1];
  209. float u = uvs[index];
  210. float v = uvs[index + 1];
  211. vertexEffect->transform(vertexEffect, &x, &y, &u, &v, &vertexColor, &dark);
  212. vertices[index] = x;
  213. vertices[index + 1] = y;
  214. spFloatArray_add(tempUvs, u);
  215. spFloatArray_add(tempUvs, v);
  216. spColorArray_add(tempColors, vertexColor);
  217. }
  218. for (int i = 0; i < indicesCount; ++i) {
  219. int index = indices[i] << 1;
  220. vertex.position.x = vertices[index];
  221. vertex.position.y = vertices[index + 1];
  222. vertex.texCoords.x = uvs[index] * size.x;
  223. vertex.texCoords.y = uvs[index + 1] * size.y;
  224. spColor vertexColor = tempColors->items[index >> 1];
  225. vertex.color.r = static_cast<Uint8>(vertexColor.r * 255);
  226. vertex.color.g = static_cast<Uint8>(vertexColor.g * 255);
  227. vertex.color.b = static_cast<Uint8>(vertexColor.b * 255);
  228. vertex.color.a = static_cast<Uint8>(vertexColor.a * 255);
  229. vertexArray->append(vertex);
  230. }
  231. } else {
  232. for (int i = 0; i < indicesCount; ++i) {
  233. int index = indices[i] << 1;
  234. vertex.position.x = vertices[index];
  235. vertex.position.y = vertices[index + 1];
  236. vertex.texCoords.x = uvs[index] * size.x;
  237. vertex.texCoords.y = uvs[index + 1] * size.y;
  238. vertexArray->append(vertex);
  239. }
  240. }
  241. spSkeletonClipping_clipEnd(clipper, slot);
  242. }
  243. target.draw(*vertexArray, states);
  244. spSkeletonClipping_clipEnd2(clipper);
  245. if (vertexEffect != 0) vertexEffect->end(vertexEffect);
  246. }
  247. } /* namespace spine */