您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

260 行
6.1 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #include <lol/engine-internal.h>
  13. #include <cstdlib>
  14. #include <cstdio>
  15. #include <cstring>
  16. #if defined _WIN32
  17. # define WIN32_LEAN_AND_MEAN
  18. # include <windows.h>
  19. # undef WIN32_LEAN_AND_MEAN
  20. #endif
  21. #include "textureimage-private.h"
  22. namespace lol
  23. {
  24. /*
  25. * TileSet implementation class
  26. */
  27. class TileSetData
  28. {
  29. friend class TileSet;
  30. protected:
  31. /* Pixels, then texture coordinates */
  32. array<ibox2, box2> m_tiles;
  33. ivec2 m_tile_size;
  34. };
  35. /*
  36. * Public TileSet class
  37. */
  38. TileSet::TileSet(std::string const &path)
  39. : TextureImage(path),
  40. m_tileset_data(new TileSetData()),
  41. m_palette(nullptr)
  42. {
  43. }
  44. TileSet::TileSet(std::string const &path, Image* image)
  45. : TextureImage(path, image),
  46. m_tileset_data(new TileSetData()),
  47. m_palette(nullptr)
  48. {
  49. }
  50. TileSet::TileSet(std::string const &path, Image* image, array<ivec2, ivec2>& tiles)
  51. : TextureImage(path, image),
  52. m_tileset_data(new TileSetData()),
  53. m_palette(nullptr)
  54. {
  55. define_tile(tiles);
  56. }
  57. TileSet::TileSet(std::string const &path, ivec2 size, ivec2 count)
  58. : TileSet(path)
  59. {
  60. /* If count is valid, fix size; otherwise, fix count. */
  61. if (count.x > 0 && count.y > 0)
  62. {
  63. size = m_data->m_image_size / count;
  64. }
  65. else
  66. {
  67. if (size.x <= 0 || size.y <= 0)
  68. size = ivec2(32, 32);
  69. count = max(ivec2(1, 1), m_data->m_image_size / size);
  70. }
  71. for (int j = 0; j < count.y; ++j)
  72. for (int i = 0; i < count.x; ++i)
  73. {
  74. define_tile(ibox2(size * ivec2(i, j),
  75. size * ivec2(i + 1, j + 1)));
  76. }
  77. }
  78. TileSet::TileSet(std::string const &path, Image* image, ivec2 size, ivec2 count)
  79. : TileSet(path, image)
  80. {
  81. /* If count is valid, fix size; otherwise, fix count. */
  82. if (count.x > 0 && count.y > 0)
  83. {
  84. size = m_data->m_image_size / count;
  85. }
  86. else
  87. {
  88. if (size.x <= 0 || size.y <= 0)
  89. size = ivec2(32, 32);
  90. count = max(ivec2(1, 1), m_data->m_image_size / size);
  91. }
  92. for (int j = 0; j < count.y; ++j)
  93. for (int i = 0; i < count.x; ++i)
  94. {
  95. define_tile(ibox2(size * ivec2(i, j),
  96. size * ivec2(i + 1, j + 1)));
  97. }
  98. }
  99. TileSet::~TileSet()
  100. {
  101. delete m_tileset_data;
  102. }
  103. void TileSet::Init(std::string const &path, ResourceCodecData* loaded_data)
  104. {
  105. //Load tileset if available
  106. auto tileset_data = dynamic_cast<ResourceTilesetData*>(loaded_data);
  107. if (tileset_data != nullptr)
  108. {
  109. define_tile(tileset_data->m_tiles);
  110. }
  111. m_data->m_name = "<tileset> " + path;
  112. super::Init(path, loaded_data);
  113. }
  114. void TileSet::Init(std::string const &path, Image* image)
  115. {
  116. super::Init(path, image);
  117. m_data->m_name = "<tileset> " + path;
  118. }
  119. //Inherited from Entity -------------------------------------------------------
  120. std::string TileSet::GetName() const
  121. {
  122. return m_data->m_name;
  123. }
  124. //New methods -----------------------------------------------------------------
  125. void TileSet::clear_all()
  126. {
  127. m_tileset_data->m_tiles.clear();
  128. }
  129. int TileSet::define_tile(ibox2 rect)
  130. {
  131. m_tileset_data->m_tiles.push(rect,
  132. box2((vec2)rect.aa / (vec2)m_data->m_texture_size,
  133. (vec2)rect.bb / (vec2)m_data->m_texture_size));
  134. return m_tileset_data->m_tiles.count() - 1;
  135. }
  136. void TileSet::define_tile(ivec2 count)
  137. {
  138. ivec2 size = m_data->m_image_size / count;
  139. for (int j = 0; j < count.y; ++j)
  140. for (int i = 0; i < count.x; ++i)
  141. {
  142. define_tile(ibox2(size * ivec2(i, j),
  143. size * ivec2(i + 1, j + 1)));
  144. }
  145. }
  146. void TileSet::define_tile(array<ibox2>& tiles)
  147. {
  148. for (int i = 0; i < tiles.count(); i++)
  149. define_tile(tiles[i]);
  150. }
  151. void TileSet::define_tile(array<ivec2, ivec2>& tiles)
  152. {
  153. for (int i = 0; i < tiles.count(); i++)
  154. define_tile(ibox2(tiles[i].m1, tiles[i].m1 + tiles[i].m2));
  155. }
  156. int TileSet::GetTileCount() const
  157. {
  158. return m_tileset_data->m_tiles.count();
  159. }
  160. ivec2 TileSet::GetTileSize(int tileid) const
  161. {
  162. return m_tileset_data->m_tiles[tileid].m1.extent();
  163. }
  164. ibox2 TileSet::GetTilePixel(int tileid) const
  165. {
  166. return m_tileset_data->m_tiles[tileid].m1;
  167. }
  168. box2 TileSet::GetTileTexel(int tileid) const
  169. {
  170. return m_tileset_data->m_tiles[tileid].m2;
  171. }
  172. //Palette ---------------------------------------------------------------------
  173. void TileSet::SetPalette(TileSet* palette)
  174. {
  175. m_palette = palette;
  176. }
  177. TileSet* TileSet::GetPalette()
  178. {
  179. return m_palette;
  180. }
  181. TileSet const* TileSet::GetPalette() const
  182. {
  183. return m_palette;
  184. }
  185. void TileSet::BlitTile(uint32_t id, mat4 model, vec3 *vertex, vec2 *texture)
  186. {
  187. ibox2 pixels = m_tileset_data->m_tiles[id].m1;
  188. box2 texels = m_tileset_data->m_tiles[id].m2;
  189. float dtx = texels.extent().x;
  190. float dty = texels.extent().y;
  191. float tx = texels.aa.x;
  192. float ty = texels.aa.y;
  193. vec3 pos = (model * vec4(0.f, 0.f, 0.f, 1.f)).xyz;
  194. vec3 extent_x = 0.5f * pixels.extent().x * (model * vec4::axis_x).xyz;
  195. vec3 extent_y = 0.5f * pixels.extent().y * (model * vec4::axis_y).xyz;
  196. if (!m_data->m_image && m_data->m_texture)
  197. {
  198. *vertex++ = pos + extent_x + extent_y;
  199. *vertex++ = pos - extent_x + extent_y;
  200. *vertex++ = pos + extent_x - extent_y;
  201. *vertex++ = pos + extent_x - extent_y;
  202. *vertex++ = pos - extent_x + extent_y;
  203. *vertex++ = pos - extent_x - extent_y;
  204. *texture++ = vec2(tx + dtx, ty);
  205. *texture++ = vec2(tx, ty);
  206. *texture++ = vec2(tx + dtx, ty + dty);
  207. *texture++ = vec2(tx + dtx, ty + dty);
  208. *texture++ = vec2(tx, ty);
  209. *texture++ = vec2(tx, ty + dty);
  210. }
  211. else
  212. {
  213. memset(vertex, 0, 6 * sizeof(vec3));
  214. memset(texture, 0, 6 * sizeof(vec2));
  215. }
  216. }
  217. } /* namespace lol */