spine-cocos2dx.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /******************************************************************************
  2. * Spine Runtimes License Agreement
  3. * Last updated January 1, 2020. Replaces all prior versions.
  4. *
  5. * Copyright (c) 2013-2020, Esoteric Software LLC
  6. *
  7. * Integration of the Spine Runtimes into software or otherwise creating
  8. * derivative works of the Spine Runtimes is permitted under the terms and
  9. * conditions of Section 2 of the Spine Editor License Agreement:
  10. * http://esotericsoftware.com/spine-editor-license
  11. *
  12. * Otherwise, it is permitted to integrate the Spine Runtimes into software
  13. * or otherwise create derivative works of the Spine Runtimes (collectively,
  14. * "Products"), provided that each user of the Products must obtain their own
  15. * Spine Editor license and redistribution of the Products in any form must
  16. * include this license and copyright notice.
  17. *
  18. * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
  19. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
  24. * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *****************************************************************************/
  29. #include <spine/spine-cocos2dx.h>
  30. #include <spine/extension.h>
  31. #include <spine/AttachmentVertices.h>
  32. USING_NS_CC;
  33. using namespace spine;
  34. static void deleteAttachmentVertices (void* vertices) {
  35. delete (AttachmentVertices *) vertices;
  36. }
  37. static unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0};
  38. static void setAttachmentVertices(RegionAttachment* attachment) {
  39. AtlasRegion* region = (AtlasRegion*)attachment->getRendererObject();
  40. AttachmentVertices* attachmentVertices = new AttachmentVertices((Texture2D*)region->page->getRendererObject(), 4, quadTriangles, 6);
  41. V3F_C4B_T2F* vertices = attachmentVertices->_triangles->verts;
  42. for (int i = 0, ii = 0; i < 4; ++i, ii += 2) {
  43. vertices[i].texCoords.u = attachment->getUVs()[ii];
  44. vertices[i].texCoords.v = attachment->getUVs()[ii + 1];
  45. }
  46. attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
  47. }
  48. static void setAttachmentVertices(MeshAttachment* attachment) {
  49. AtlasRegion* region = (AtlasRegion*)attachment->getRendererObject();
  50. AttachmentVertices* attachmentVertices = new AttachmentVertices((Texture2D*)region->page->getRendererObject(),
  51. attachment->getWorldVerticesLength() >> 1, attachment->getTriangles().buffer(), attachment->getTriangles().size());
  52. V3F_C4B_T2F* vertices = attachmentVertices->_triangles->verts;
  53. for (int i = 0, ii = 0, nn = attachment->getWorldVerticesLength(); ii < nn; ++i, ii += 2) {
  54. vertices[i].texCoords.u = attachment->getUVs()[ii];
  55. vertices[i].texCoords.v = attachment->getUVs()[ii + 1];
  56. }
  57. attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
  58. }
  59. Cocos2dAtlasAttachmentLoader::Cocos2dAtlasAttachmentLoader(Atlas* atlas): AtlasAttachmentLoader(atlas) {
  60. }
  61. Cocos2dAtlasAttachmentLoader::~Cocos2dAtlasAttachmentLoader() { }
  62. void Cocos2dAtlasAttachmentLoader::configureAttachment(Attachment* attachment) {
  63. if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
  64. setAttachmentVertices((RegionAttachment*)attachment);
  65. } else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
  66. setAttachmentVertices((MeshAttachment*)attachment);
  67. }
  68. }
  69. #if COCOS2D_VERSION >= 0x0040000
  70. backend::SamplerAddressMode wrap (TextureWrap wrap) {
  71. return wrap == TextureWrap_ClampToEdge ? backend::SamplerAddressMode::CLAMP_TO_EDGE : backend::SamplerAddressMode::REPEAT;
  72. }
  73. backend::SamplerFilter filter (TextureFilter filter) {
  74. switch (filter) {
  75. case TextureFilter_Unknown:
  76. break;
  77. case TextureFilter_Nearest:
  78. return backend::SamplerFilter::NEAREST;
  79. case TextureFilter_Linear:
  80. return backend::SamplerFilter::LINEAR;
  81. case TextureFilter_MipMap:
  82. return backend::SamplerFilter::LINEAR;
  83. case TextureFilter_MipMapNearestNearest:
  84. return backend::SamplerFilter::NEAREST;
  85. case TextureFilter_MipMapLinearNearest:
  86. return backend::SamplerFilter::NEAREST;
  87. case TextureFilter_MipMapNearestLinear:
  88. return backend::SamplerFilter::LINEAR;
  89. case TextureFilter_MipMapLinearLinear:
  90. return backend::SamplerFilter::LINEAR;
  91. }
  92. return backend::SamplerFilter::LINEAR;
  93. }
  94. #else
  95. GLuint wrap (TextureWrap wrap) {
  96. return wrap == TextureWrap_ClampToEdge ? GL_CLAMP_TO_EDGE : GL_REPEAT;
  97. }
  98. GLuint filter (TextureFilter filter) {
  99. switch (filter) {
  100. case TextureFilter_Unknown:
  101. break;
  102. case TextureFilter_Nearest:
  103. return GL_NEAREST;
  104. case TextureFilter_Linear:
  105. return GL_LINEAR;
  106. case TextureFilter_MipMap:
  107. return GL_LINEAR_MIPMAP_LINEAR;
  108. case TextureFilter_MipMapNearestNearest:
  109. return GL_NEAREST_MIPMAP_NEAREST;
  110. case TextureFilter_MipMapLinearNearest:
  111. return GL_LINEAR_MIPMAP_NEAREST;
  112. case TextureFilter_MipMapNearestLinear:
  113. return GL_NEAREST_MIPMAP_LINEAR;
  114. case TextureFilter_MipMapLinearLinear:
  115. return GL_LINEAR_MIPMAP_LINEAR;
  116. }
  117. return GL_LINEAR;
  118. }
  119. #endif
  120. Cocos2dTextureLoader::Cocos2dTextureLoader() : TextureLoader() { }
  121. Cocos2dTextureLoader::~Cocos2dTextureLoader() { }
  122. void Cocos2dTextureLoader::load(AtlasPage& page, const spine::String& path) {
  123. Texture2D* texture = Director::getInstance()->getTextureCache()->addImage(path.buffer());
  124. CCASSERT(texture != nullptr, "Invalid image");
  125. if (texture) {
  126. texture->retain();
  127. #if COCOS2D_VERSION >= 0x0040000
  128. Texture2D::TexParams textureParams(filter(page.minFilter), filter(page.magFilter), wrap(page.uWrap), wrap(page.vWrap));
  129. #else
  130. Texture2D::TexParams textureParams = {filter(page.minFilter), filter(page.magFilter), wrap(page.uWrap), wrap(page.vWrap)};
  131. #endif
  132. texture->setTexParameters(textureParams);
  133. page.setRendererObject(texture);
  134. page.width = texture->getPixelsWide();
  135. page.height = texture->getPixelsHigh();
  136. }
  137. }
  138. void Cocos2dTextureLoader::unload(void* texture) {
  139. if (texture) {
  140. ((Texture2D*)texture)->release();
  141. }
  142. }
  143. Cocos2dExtension::Cocos2dExtension() : DefaultSpineExtension() { }
  144. Cocos2dExtension::~Cocos2dExtension() { }
  145. char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
  146. Data data = FileUtils::getInstance()->getDataFromFile(FileUtils::getInstance()->fullPathForFilename(path.buffer()));
  147. if (data.isNull()) return nullptr;
  148. // avoid buffer overflow (int is shorter than ssize_t in certain platforms)
  149. #if COCOS2D_VERSION >= 0x00031200
  150. ssize_t tmpLen;
  151. char *ret = (char*)data.takeBuffer(&tmpLen);
  152. *length = static_cast<int>(tmpLen);
  153. return ret;
  154. #else
  155. *length = static_cast<int>(data.getSize());
  156. char* bytes = MALLOC(char, *length);
  157. memcpy(bytes, data.getBytes(), *length);
  158. return bytes;
  159. #endif
  160. }
  161. void Cocos2dExtension::createSpriteFrame(Atlas* atlas){
  162. auto _regions = atlas->getRegions();
  163. auto len = _regions.size();
  164. if(len==0)return;
  165. for (int i = 0;i<len;i++) {
  166. auto region = _regions[i];
  167. float width = region->originalWidth;
  168. float height = region->originalHeight;
  169. float wh = region->width;
  170. float sh = region->height;
  171. if(region->rotate){
  172. // std::swap(width, height);
  173. std::swap(wh, sh);
  174. }
  175. Rect rect = Rect(region->x, region->y, wh, sh);
  176. Vec2 offset = Vec2(region->offsetX,region->offsetY);
  177. Size originSize = Size(width,height);
  178. String path = region->page->name;
  179. auto frame = SpriteFrame::create(path.buffer(), rect, region->rotate, offset, originSize);
  180. std::string name = region->name.buffer();
  181. name.append(".png");
  182. SpriteFrameCache::getInstance()->addSpriteFrame(frame,name);
  183. }
  184. }
  185. SpineExtension *spine::getDefaultExtension () {
  186. return new Cocos2dExtension();
  187. }