wrap_SpriteBatch.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /**
  2. * Copyright (c) 2006-2016 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. // LOVE
  21. #include "wrap_SpriteBatch.h"
  22. #include "Image.h"
  23. #include "Canvas.h"
  24. #include "graphics/wrap_Texture.h"
  25. // C++
  26. #include <typeinfo>
  27. namespace love
  28. {
  29. namespace graphics
  30. {
  31. namespace opengl
  32. {
  33. SpriteBatch *luax_checkspritebatch(lua_State *L, int idx)
  34. {
  35. return luax_checktype<SpriteBatch>(L, idx);
  36. }
  37. static inline int w_SpriteBatch_add_or_set(lua_State *L, SpriteBatch *t, int startidx, int index)
  38. {
  39. Quad *quad = nullptr;
  40. if (luax_istype(L, startidx, Quad::type))
  41. {
  42. quad = luax_totype<Quad>(L, startidx);
  43. startidx++;
  44. }
  45. else if (lua_isnil(L, startidx) && !lua_isnoneornil(L, startidx + 1))
  46. return luax_typerror(L, startidx, "Quad");
  47. float x = (float) luaL_optnumber(L, startidx + 0, 0.0);
  48. float y = (float) luaL_optnumber(L, startidx + 1, 0.0);
  49. float a = (float) luaL_optnumber(L, startidx + 2, 0.0);
  50. float sx = (float) luaL_optnumber(L, startidx + 3, 1.0);
  51. float sy = (float) luaL_optnumber(L, startidx + 4, sx);
  52. float ox = (float) luaL_optnumber(L, startidx + 5, 0.0);
  53. float oy = (float) luaL_optnumber(L, startidx + 6, 0.0);
  54. float kx = (float) luaL_optnumber(L, startidx + 7, 0.0);
  55. float ky = (float) luaL_optnumber(L, startidx + 8, 0.0);
  56. Matrix4 m(x, y, a, sx, sy, ox, oy, kx, ky);
  57. luax_catchexcept(L, [&]() {
  58. if (quad)
  59. index = t->addq(quad, m, index);
  60. else
  61. index = t->add(m, index);
  62. });
  63. return index;
  64. }
  65. int w_SpriteBatch_add(lua_State *L)
  66. {
  67. SpriteBatch *t = luax_checkspritebatch(L, 1);
  68. int index = w_SpriteBatch_add_or_set(L, t, 2, -1);
  69. lua_pushinteger(L, index + 1);
  70. return 1;
  71. }
  72. int w_SpriteBatch_set(lua_State *L)
  73. {
  74. SpriteBatch *t = luax_checkspritebatch(L, 1);
  75. int index = (int) luaL_checknumber(L, 2) - 1;
  76. w_SpriteBatch_add_or_set(L, t, 3, index);
  77. return 0;
  78. }
  79. int w_SpriteBatch_clear(lua_State *L)
  80. {
  81. SpriteBatch *t = luax_checkspritebatch(L, 1);
  82. t->clear();
  83. return 0;
  84. }
  85. int w_SpriteBatch_flush(lua_State *L)
  86. {
  87. SpriteBatch *t = luax_checkspritebatch(L, 1);
  88. t->flush();
  89. return 0;
  90. }
  91. int w_SpriteBatch_setTexture(lua_State *L)
  92. {
  93. SpriteBatch *t = luax_checkspritebatch(L, 1);
  94. Texture *tex = luax_checktexture(L, 2);
  95. t->setTexture(tex);
  96. return 0;
  97. }
  98. int w_SpriteBatch_getTexture(lua_State *L)
  99. {
  100. SpriteBatch *t = luax_checkspritebatch(L, 1);
  101. Texture *tex = t->getTexture();
  102. // FIXME: big hack right here.
  103. if (typeid(*tex) == typeid(Image))
  104. luax_pushtype(L, Image::type, tex);
  105. else if (typeid(*tex) == typeid(Canvas))
  106. luax_pushtype(L, Canvas::type, tex);
  107. else
  108. return luaL_error(L, "Unable to determine texture type.");
  109. return 1;
  110. }
  111. int w_SpriteBatch_setColor(lua_State *L)
  112. {
  113. SpriteBatch *t = luax_checkspritebatch(L, 1);
  114. Color c;
  115. if (lua_gettop(L) <= 1)
  116. {
  117. t->setColor();
  118. return 0;
  119. }
  120. else if (lua_istable(L, 2))
  121. {
  122. for (int i = 1; i <= 4; i++)
  123. lua_rawgeti(L, 2, i);
  124. c.r = (unsigned char) (luaL_checknumber(L, -4) * 255.0);
  125. c.g = (unsigned char) (luaL_checknumber(L, -3) * 255.0);
  126. c.b = (unsigned char) (luaL_checknumber(L, -2) * 255.0);
  127. c.a = (unsigned char) (luaL_optnumber(L, -1, 1.0) * 255.0);
  128. lua_pop(L, 4);
  129. }
  130. else
  131. {
  132. c.r = (unsigned char) (luaL_checknumber(L, 2) * 255.0);
  133. c.g = (unsigned char) (luaL_checknumber(L, 3) * 255.0);
  134. c.b = (unsigned char) (luaL_checknumber(L, 4) * 255.0);
  135. c.a = (unsigned char) (luaL_optnumber(L, 5, 1.0) * 255.0);
  136. }
  137. t->setColor(c);
  138. return 0;
  139. }
  140. int w_SpriteBatch_getColor(lua_State *L)
  141. {
  142. SpriteBatch *t = luax_checkspritebatch(L, 1);
  143. const Color *color = t->getColor();
  144. // getColor returns null if no color is set.
  145. if (!color)
  146. return 0;
  147. lua_pushnumber(L, (lua_Number) color->r / 255.0);
  148. lua_pushnumber(L, (lua_Number) color->g / 255.0);
  149. lua_pushnumber(L, (lua_Number) color->b / 255.0);
  150. lua_pushnumber(L, (lua_Number) color->a / 255.0);
  151. return 4;
  152. }
  153. int w_SpriteBatch_getCount(lua_State *L)
  154. {
  155. SpriteBatch *t = luax_checkspritebatch(L, 1);
  156. lua_pushinteger(L, t->getCount());
  157. return 1;
  158. }
  159. int w_SpriteBatch_getBufferSize(lua_State *L)
  160. {
  161. SpriteBatch *t = luax_checkspritebatch(L, 1);
  162. lua_pushinteger(L, t->getBufferSize());
  163. return 1;
  164. }
  165. int w_SpriteBatch_attachAttribute(lua_State *L)
  166. {
  167. SpriteBatch *t = luax_checkspritebatch(L, 1);
  168. const char *name = luaL_checkstring(L, 2);
  169. Mesh *m = luax_checktype<Mesh>(L, 3);
  170. luax_catchexcept(L, [&](){ t->attachAttribute(name, m); });
  171. return 0;
  172. }
  173. int w_SpriteBatch_setDrawRange(lua_State *L)
  174. {
  175. SpriteBatch *t = luax_checkspritebatch(L, 1);
  176. if (lua_isnoneornil(L, 2))
  177. t->setDrawRange();
  178. else
  179. {
  180. int start = (int) luaL_checknumber(L, 2) - 1;
  181. int count = (int) luaL_checknumber(L, 3);
  182. luax_catchexcept(L, [&](){ t->setDrawRange(start, count); });
  183. }
  184. return 0;
  185. }
  186. int w_SpriteBatch_getDrawRange(lua_State *L)
  187. {
  188. SpriteBatch *t = luax_checkspritebatch(L, 1);
  189. int start = 0;
  190. int count = 1;
  191. if (!t->getDrawRange(start, count))
  192. return 0;
  193. lua_pushnumber(L, start + 1);
  194. lua_pushnumber(L, count);
  195. return 2;
  196. }
  197. static const luaL_Reg w_SpriteBatch_functions[] =
  198. {
  199. { "add", w_SpriteBatch_add },
  200. { "set", w_SpriteBatch_set },
  201. { "clear", w_SpriteBatch_clear },
  202. { "flush", w_SpriteBatch_flush },
  203. { "setTexture", w_SpriteBatch_setTexture },
  204. { "getTexture", w_SpriteBatch_getTexture },
  205. { "setColor", w_SpriteBatch_setColor },
  206. { "getColor", w_SpriteBatch_getColor },
  207. { "getCount", w_SpriteBatch_getCount },
  208. { "getBufferSize", w_SpriteBatch_getBufferSize },
  209. { "attachAttribute", w_SpriteBatch_attachAttribute },
  210. { "setDrawRange", w_SpriteBatch_setDrawRange },
  211. { "getDrawRange", w_SpriteBatch_getDrawRange },
  212. { 0, 0 }
  213. };
  214. extern "C" int luaopen_spritebatch(lua_State *L)
  215. {
  216. return luax_register_type(L, SpriteBatch::type, w_SpriteBatch_functions, nullptr);
  217. }
  218. } // opengl
  219. } // graphics
  220. } // love