Sprite.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /*
  2. Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
  3. Permission is hereby granted, free of charge, to any person
  4. obtaining a copy of this software and associated documentation
  5. files (the "Software"), to deal in the Software without
  6. restriction, including without limitation the rights to use,
  7. copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. copies of the Software, and to permit persons to whom the
  9. Software is furnished to do so, subject to the following
  10. conditions:
  11. The above copyright notice and this permission notice shall be
  12. included in all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  15. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  17. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  18. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. #include "Sprite.h"
  23. #include "Types.h"
  24. #include "Device.h"
  25. #include "Renderer.h"
  26. #include "Log.h"
  27. #include "BMPImageLoader.h"
  28. #include "TextureManager.h"
  29. #include "VertexBuffer.h"
  30. #include "IndexBuffer.h"
  31. namespace Crown
  32. {
  33. Sprite::Sprite():
  34. mInterpolate(false)
  35. {
  36. mVertices[0] = VertexData(Vec3(-1.0f, -1.0f, 0.0f), Vec3(0, 0, 1.0f), Vec2(0.0f, 0.0f), Color4::WHITE);
  37. mVertices[1] = VertexData(Vec3(+1.0f, -1.0f, 0.0f), Vec3(0, 0, 1.0f), Vec2(1.0f, 0.0f), Color4::WHITE);
  38. mVertices[2] = VertexData(Vec3(+1.0f, +1.0f, 0.0f), Vec3(0, 0, 1.0f), Vec2(1.0f, 1.0f), Color4::WHITE);
  39. mVertices[3] = VertexData(Vec3(-1.0f, +1.0f, 0.0f), Vec3(0, 0, 1.0f), Vec2(0.0f, 1.0f), Color4::WHITE);
  40. mFaces[0] = FaceData(0, 1, 2);
  41. mFaces[1] = FaceData(0, 2, 3);
  42. mVertexBuffer = GetDevice()->GetRenderer()->CreateVertexBuffer();
  43. mIndexBuffer = GetDevice()->GetRenderer()->CreateIndexBuffer();
  44. mVertexBuffer->SetVertexData((VertexBufferMode) (VBM_TEXTURE_COORDS | VBM_NORMAL_COORDS | VBM_COLOR_COORDS), (float*) &mVertices[0], 4);
  45. mIndexBuffer->SetIndexData(&mFaces[0].vertex[0], 6);
  46. }
  47. Sprite::~Sprite()
  48. {
  49. for (int i=0; i<mFrames.GetSize(); i++)
  50. {
  51. delete mFrames[i];
  52. }
  53. }
  54. void Sprite::Clear()
  55. {
  56. while (mFrames.GetSize() > 0)
  57. {
  58. RemoveFrame(0);
  59. }
  60. }
  61. void Sprite::SetInterpolation(bool interpolate)
  62. {
  63. mInterpolate = interpolate;
  64. }
  65. void Sprite::RemoveFrame(int frameNumber)
  66. {
  67. if (frameNumber >= mFrames.GetSize())
  68. {
  69. Log::E("Sprite::RemoveFrame frameNumber out of array");
  70. return;
  71. }
  72. delete mFrames[frameNumber];
  73. mFrames.Remove(frameNumber);
  74. }
  75. void Sprite::draw(int frameNumber)
  76. {
  77. draw(frameNumber, 0.0, 1.0, 1.0);
  78. }
  79. void Sprite::draw(int frameNumber, real angle, real scaleX, real scaleY)
  80. {
  81. if (frameNumber >= mFrames.GetSize())
  82. {
  83. Log::E("Sprite::draw frameNumber out of array");
  84. return;
  85. }
  86. Renderer* renderer = GetDevice()->GetRenderer();
  87. Frame* frame = mFrames[frameNumber];
  88. renderer->_SetTexturing(0, true);
  89. renderer->_SetTexture(0, frame->mTexture);
  90. renderer->_SetTextureMode(0, frame->mTexture->GetMode(), frame->mTexture->GetBlendColor());
  91. if (mInterpolate)
  92. {
  93. renderer->_SetTextureFilter(0, TF_LINEAR);
  94. }
  95. else
  96. {
  97. renderer->_SetTextureFilter(0, TF_NEAREST);
  98. }
  99. renderer->_SetBlending(true);
  100. // Setup transformation
  101. Mat4 transformation;
  102. transformation.BuildRotationZ(angle);
  103. transformation.SetTranslation(Vec3(-frame->mOffset.x, -frame->mOffset.y, 0.0f));
  104. Mat4 s;
  105. s.LoadIdentity();
  106. s.SetScale(Vec3(scaleX, scaleY, 0.0f));
  107. transformation = s * transformation;
  108. // Update vertex data
  109. mVertices[0].position.x = 0.0f;
  110. mVertices[0].position.y = 0.0f;
  111. mVertices[1].position.x = frame->mSize.x;
  112. mVertices[1].position.y = 0.0f;
  113. mVertices[2].position.x = frame->mSize.x;
  114. mVertices[2].position.y = frame->mSize.y;
  115. mVertices[3].position.x = 0.0f;
  116. mVertices[3].position.y = frame->mSize.y;
  117. mVertices[0].uv.x = frame->mTextureRect.min.x;
  118. mVertices[0].uv.y = frame->mTextureRect.min.y;
  119. mVertices[1].uv.x = frame->mTextureRect.max.x;
  120. mVertices[1].uv.y = frame->mTextureRect.min.y;
  121. mVertices[2].uv.x = frame->mTextureRect.max.x;
  122. mVertices[2].uv.y = frame->mTextureRect.max.y;
  123. mVertices[3].uv.x = frame->mTextureRect.min.x;
  124. mVertices[3].uv.y = frame->mTextureRect.max.y;
  125. // Update vertex buffer
  126. mVertexBuffer->SetVertexSubData((float*) &mVertices[0], 0, 4);
  127. // Set transformation matrix and draw
  128. renderer->SetMatrix(MT_MODEL, transformation);
  129. renderer->RenderVertexIndexBuffer(mVertexBuffer, mIndexBuffer);
  130. renderer->_SetBlending(false);
  131. renderer->_SetTexturing(0, false);
  132. }
  133. void Sprite::drawFit(int frameNumber, int x, int y, int w, int h)
  134. {
  135. Renderer* renderer = GetDevice()->GetRenderer();
  136. Frame* frame = mFrames[frameNumber];
  137. renderer->_SetTexturing(0, true);
  138. renderer->_SetTexture(0, frame->mTexture);
  139. renderer->_SetTextureMode(0, frame->mTexture->GetMode(), frame->mTexture->GetBlendColor());
  140. renderer->_SetTextureFilter(0, frame->mTexture->GetFilter());
  141. renderer->_SetBlending(true);
  142. // Setup transformation
  143. Mat4 transformation;
  144. transformation.LoadIdentity();
  145. transformation.SetTranslation(Vec3(-frame->mOffset.x, -frame->mOffset.y, 0.0f));
  146. Mat4 transformation2;
  147. transformation2.LoadIdentity();
  148. transformation2.SetTranslation(Vec3(x, y, 0.0f));
  149. transformation = transformation * transformation2;
  150. // Update vertex data
  151. mVertices[0].position.x = 0.0f;
  152. mVertices[0].position.y = 0.0f;
  153. mVertices[1].position.x = (float)w;
  154. mVertices[1].position.y = 0.0f;
  155. mVertices[2].position.x = (float)w;
  156. mVertices[2].position.y = (float)h;
  157. mVertices[3].position.x = 0.0f;
  158. mVertices[3].position.y = (float)h;
  159. mVertices[0].uv.x = frame->mTextureRect.min.x;
  160. mVertices[0].uv.y = frame->mTextureRect.min.y;
  161. mVertices[1].uv.x = frame->mTextureRect.max.x;
  162. mVertices[1].uv.y = frame->mTextureRect.min.y;
  163. mVertices[2].uv.x = frame->mTextureRect.max.x;
  164. mVertices[2].uv.y = frame->mTextureRect.max.y;
  165. mVertices[3].uv.x = frame->mTextureRect.min.x;
  166. mVertices[3].uv.y = frame->mTextureRect.max.y;
  167. // Update vertex buffer
  168. mVertexBuffer->SetVertexSubData((float*) &mVertices[0], 0, 4);
  169. // Set transformation matrix and draw
  170. renderer->SetMatrix(MT_MODEL, transformation);
  171. renderer->RenderVertexIndexBuffer(mVertexBuffer, mIndexBuffer);
  172. renderer->_SetBlending(false);
  173. renderer->_SetTexturing(0, false);
  174. }
  175. Sprite* Sprite::LoadSpriteFromImage(const char* filePath)
  176. {
  177. Renderer* renderer = GetDevice()->GetRenderer();
  178. Frame* f;
  179. Sprite* sprite;
  180. Texture* texture = GetTextureManager()->Load(filePath, false, Color4(255, 0, 255));
  181. texture->SetWrap(TW_CLAMP);
  182. f = new Frame();
  183. f->Set(texture);
  184. sprite = new Sprite();
  185. sprite->AddFrame(f);
  186. return sprite;
  187. }
  188. Sprite* Sprite::LoadSpriteFromImage(const char* filePath, uint tileCount, uint tileRows, uint tileColumns, uint imgX, uint imgY, uint tileSizeX, uint tileSizeY, uint tilePadX, uint tilePadY)
  189. {
  190. Renderer* renderer = GetDevice()->GetRenderer();
  191. Frame* f;
  192. Sprite* sprite;
  193. Texture* texture = GetTextureManager()->Load(filePath, false, Color4(255, 0, 255));
  194. texture->SetWrap(TW_CLAMP);
  195. sprite = new Sprite();
  196. uint texHeight = texture->GetHeight();
  197. for(int row = 0; row < tileRows; row++)
  198. {
  199. for(int col = 0; col < tileColumns; col++)
  200. {
  201. f = new Frame();
  202. uint x = imgX + col * (tileSizeX + tilePadX);
  203. uint y = imgY + row * (tileSizeY + tilePadY);
  204. f->Set(texture, x, texHeight - (y + tileSizeY), x + tileSizeX, texHeight - y);
  205. sprite->AddFrame(f);
  206. if (sprite->GetFrameCount() == tileCount)
  207. {
  208. return sprite;
  209. }
  210. }
  211. }
  212. return sprite;
  213. }
  214. Sprite* Sprite::LoadSpriteFromImage(const char* filePath, const char* alphaFilePath, uint tileCount, uint tileRows, uint tileColumns, uint imgX, uint imgY, uint tileSizeX, uint tileSizeY, uint tilePadX, uint tilePadY)
  215. {
  216. Renderer* renderer = GetDevice()->GetRenderer();
  217. Frame* f;
  218. Sprite* sprite;
  219. Texture* texture = GetTextureManager()->Load(filePath, alphaFilePath, false);
  220. texture->SetWrap(TW_CLAMP);
  221. sprite = new Sprite();
  222. uint texHeight = texture->GetHeight();
  223. for(int row = 0; row < tileRows; row++)
  224. {
  225. for(int col = 0; col < tileColumns; col++)
  226. {
  227. f = new Frame();
  228. uint x = imgX + col * (tileSizeX + tilePadX);
  229. uint y = imgY + row * (tileSizeY + tilePadY);
  230. f->Set(texture, x, texHeight - (y + tileSizeY), x + tileSizeX, texHeight - y);
  231. sprite->AddFrame(f);
  232. if (sprite->GetFrameCount() == tileCount)
  233. {
  234. return sprite;
  235. }
  236. }
  237. }
  238. return sprite;
  239. }
  240. } //namespace Crown