You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 12 години
преди 14 години
преди 14 години
преди 11 години
преди 11 години
преди 14 години
преди 14 години
преди 14 години
преди 14 години
преди 14 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstdlib>
  14. #include <cstdio>
  15. #include <cstring>
  16. #if defined WIN32 && !defined _XBOX
  17. # define WIN32_LEAN_AND_MEAN
  18. # include <windows.h>
  19. # if defined USE_D3D9
  20. # define FAR
  21. # define NEAR
  22. # include <d3d9.h>
  23. # endif
  24. #endif
  25. #include "core.h"
  26. using namespace std;
  27. namespace lol
  28. {
  29. /*
  30. * TileSet implementation class
  31. */
  32. class TileSetData
  33. {
  34. friend class TileSet;
  35. private:
  36. String m_name;
  37. /* Pixels, then texture coordinates */
  38. Array<ibox2, box2> m_tiles;
  39. ivec2 m_tile_size, m_image_size, m_texture_size;
  40. Image *m_image;
  41. Texture *m_texture;
  42. };
  43. /*
  44. * Public TileSet class
  45. */
  46. TileSet::TileSet(char const *path)
  47. : m_data(new TileSetData())
  48. {
  49. Init(path);
  50. }
  51. TileSet::TileSet(char const *path, ivec2 size, ivec2 count)
  52. : m_data(new TileSetData())
  53. {
  54. Init(path);
  55. /* If count is valid, fix size; otherwise, fix count. */
  56. if (count.x > 0 && count.y > 0)
  57. {
  58. size = m_data->m_image_size / count;
  59. }
  60. else
  61. {
  62. if (size.x <= 0 || size.y <= 0)
  63. size = ivec2(32, 32);
  64. count = max(ivec2(1, 1), m_data->m_image_size / size);
  65. }
  66. for (int j = 0; j < count.y; ++j)
  67. for (int i = 0; i < count.x; ++i)
  68. {
  69. AddTile(ibox2(size * ivec2(i, j),
  70. size * ivec2(i + 1, j + 1)));
  71. }
  72. }
  73. void TileSet::Init(char const *path)
  74. {
  75. m_data->m_name = String("<tileset> ") + path;
  76. m_data->m_texture = 0;
  77. m_data->m_image = Image::Create(path);
  78. m_data->m_image_size = m_data->m_image->GetSize();
  79. m_data->m_texture_size = ivec2(PotUp(m_data->m_image_size.x),
  80. PotUp(m_data->m_image_size.y));
  81. m_drawgroup = DRAWGROUP_BEFORE;
  82. }
  83. int TileSet::AddTile(ibox2 rect)
  84. {
  85. m_data->m_tiles.Push(rect,
  86. box2((vec2)rect.A / (vec2)m_data->m_texture_size,
  87. (vec2)rect.B / (vec2)m_data->m_texture_size));
  88. return m_data->m_tiles.Count() - 1;
  89. }
  90. TileSet::~TileSet()
  91. {
  92. delete m_data;
  93. }
  94. void TileSet::TickDraw(float seconds)
  95. {
  96. Entity::TickDraw(seconds);
  97. if (IsDestroying())
  98. {
  99. if (m_data->m_image)
  100. {
  101. Image::Destroy(m_data->m_image);
  102. m_data->m_image = nullptr;
  103. }
  104. else
  105. {
  106. delete m_data->m_texture;
  107. m_data->m_texture = nullptr;
  108. }
  109. }
  110. else if (m_data->m_image)
  111. {
  112. PixelFormat format = m_data->m_image->GetFormat();
  113. int planes = format.BytesPerPixel();
  114. int w = m_data->m_texture_size.x;
  115. int h = m_data->m_texture_size.y;
  116. uint8_t *pixels = m_data->m_image->GetData();
  117. if (w != m_data->m_image_size.x || h != m_data->m_image_size.y)
  118. {
  119. uint8_t *tmp = new uint8_t[planes * w * h];
  120. for (int line = 0; line < m_data->m_image_size.y; line++)
  121. memcpy(tmp + planes * w * line,
  122. pixels + planes * m_data->m_image_size.x * line,
  123. planes * m_data->m_image_size.x);
  124. pixels = tmp;
  125. }
  126. m_data->m_texture = new Texture(ivec2(w, h), format);
  127. m_data->m_texture->SetData(pixels);
  128. if (pixels != m_data->m_image->GetData())
  129. delete[] pixels;
  130. Image::Destroy(m_data->m_image);
  131. m_data->m_image = nullptr;
  132. }
  133. }
  134. char const *TileSet::GetName()
  135. {
  136. return m_data->m_name.C();
  137. }
  138. int TileSet::GetTileCount() const
  139. {
  140. return m_data->m_tiles.Count();
  141. }
  142. ivec2 TileSet::GetTileSize(int tileid) const
  143. {
  144. ibox2 const &box = m_data->m_tiles[tileid].m1;
  145. return box.B - box.A;
  146. }
  147. ivec2 TileSet::GetTextureSize() const
  148. {
  149. return m_data->m_texture_size;
  150. }
  151. ShaderTexture TileSet::GetTexture() const
  152. {
  153. return m_data->m_texture->GetTexture();
  154. }
  155. void TileSet::Bind()
  156. {
  157. if (!m_data->m_image && m_data->m_texture)
  158. m_data->m_texture->Bind();
  159. }
  160. void TileSet::Unbind()
  161. {
  162. ;
  163. }
  164. void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale,
  165. float *vertex, float *texture)
  166. {
  167. ibox2 pixels = m_data->m_tiles[id].m1;
  168. box2 texels = m_data->m_tiles[id].m2;
  169. float dtx = texels.B.x - texels.A.x;
  170. float dty = texels.B.y - texels.A.y;
  171. float tx = texels.A.x;
  172. float ty = texels.A.y;
  173. int dx = (pixels.B.x - pixels.A.x) * scale.x;
  174. int dy = o ? 0 : (pixels.B.y - pixels.A.y) * scale.y;
  175. int dz = o ? (pixels.B.y - pixels.A.y) * scale.y : 0;
  176. /* If scaling is negative, switch triangle winding */
  177. if (scale.x * scale.y < 0.0f)
  178. {
  179. pos.x += dx;
  180. dx = -dx;
  181. tx += dtx;
  182. dtx = -dtx;
  183. }
  184. #if 1
  185. /* HACK: tweak UV values */
  186. tx += (1.f / 128.f) * dtx;
  187. ty += (1.f / 128.f) * dty;
  188. dtx *= 126.f / 128.f;
  189. dty *= 126.f / 128.f;
  190. #endif
  191. if (!m_data->m_image && m_data->m_texture)
  192. {
  193. float tmp[10];
  194. *vertex++ = pos.x + dx;
  195. *vertex++ = pos.y + dy;
  196. *vertex++ = pos.z + dz;
  197. *texture++ = tx + dtx;
  198. *texture++ = ty;
  199. *vertex++ = tmp[0] = pos.x;
  200. *vertex++ = tmp[1] = pos.y + dy;
  201. *vertex++ = tmp[2] = pos.z + dz;
  202. *texture++ = tmp[3] = tx;
  203. *texture++ = tmp[4] = ty;
  204. *vertex++ = tmp[5] = pos.x + dx;
  205. *vertex++ = tmp[6] = pos.y;
  206. *vertex++ = tmp[7] = pos.z;
  207. *texture++ = tmp[8] = tx + dtx;
  208. *texture++ = tmp[9] = ty + dty;
  209. *vertex++ = tmp[5];
  210. *vertex++ = tmp[6];
  211. *vertex++ = tmp[7];
  212. *texture++ = tmp[8];
  213. *texture++ = tmp[9];
  214. *vertex++ = tmp[0];
  215. *vertex++ = tmp[1];
  216. *vertex++ = tmp[2];
  217. *texture++ = tmp[3];
  218. *texture++ = tmp[4];
  219. *vertex++ = pos.x;
  220. *vertex++ = pos.y;
  221. *vertex++ = pos.z;
  222. *texture++ = tx;
  223. *texture++ = ty + dty;
  224. }
  225. else
  226. {
  227. memset(vertex, 0, 3 * sizeof(float));
  228. memset(texture, 0, 2 * sizeof(float));
  229. }
  230. }
  231. } /* namespace lol */