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.

преди 13 години
преди 14 години
преди 14 години
преди 14 години
преди 14 години
преди 14 години
преди 14 години
преди 14 години
преди 14 години
преди 13 години
преди 14 години
преди 13 години
преди 13 години
преди 13 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2012 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://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstdlib>
  14. #ifdef WIN32
  15. # define WIN32_LEAN_AND_MEAN
  16. # include <windows.h>
  17. #endif
  18. #include "core.h"
  19. #include "lolgl.h"
  20. extern char const *lolfx_tile;
  21. namespace lol
  22. {
  23. struct Tile
  24. {
  25. TileSet *tileset;
  26. uint32_t prio;
  27. vec3 pos;
  28. vec2 scale;
  29. int id, o;
  30. };
  31. /*
  32. * Scene implementation class
  33. */
  34. class SceneData
  35. {
  36. friend class Scene;
  37. private:
  38. static int Compare(void const *p1, void const *p2)
  39. {
  40. Tile const *t1 = (Tile const *)p1;
  41. Tile const *t2 = (Tile const *)p2;
  42. return t2->prio - t1->prio;
  43. }
  44. mat4 m_model_matrix;
  45. mat4 m_view_matrix;
  46. mat4 m_proj_matrix;
  47. Array<Tile> tiles;
  48. Shader *m_shader;
  49. VertexDeclaration *m_vdecl;
  50. Array<VertexBuffer *> bufs;
  51. static Scene *scene;
  52. };
  53. Scene *SceneData::scene = NULL;
  54. /*
  55. * Public Scene class
  56. */
  57. Scene::Scene()
  58. : data(new SceneData())
  59. {
  60. data->m_model_matrix = mat4(1.f);
  61. data->m_view_matrix = mat4(1.f);
  62. data->m_proj_matrix = mat4::ortho(0, Video::GetSize().x,
  63. 0, Video::GetSize().y, -1000.f, 1000.f);
  64. data->m_shader = 0;
  65. data->m_vdecl = new VertexDeclaration(VertexStream<vec3>(VertexUsage::Position),
  66. VertexStream<vec2>(VertexUsage::TexCoord));
  67. }
  68. Scene::~Scene()
  69. {
  70. /* FIXME: this must be done while the GL context is still active.
  71. * Change the code architecture to make sure of that. */
  72. /* FIXME: also, make sure we do not add code to Reset() that will
  73. * reallocate stuff */
  74. Reset();
  75. delete data->m_vdecl;
  76. delete data;
  77. }
  78. Scene *Scene::GetDefault()
  79. {
  80. if (!SceneData::scene)
  81. SceneData::scene = new Scene();
  82. return SceneData::scene;
  83. }
  84. void Scene::Reset()
  85. {
  86. for (int i = 0; i < data->bufs.Count(); i++)
  87. delete data->bufs[i];
  88. data->bufs.Empty();
  89. }
  90. void Scene::SetViewMatrix(mat4 const &m)
  91. {
  92. data->m_view_matrix = m;
  93. }
  94. void Scene::SetProjMatrix(mat4 const &m)
  95. {
  96. data->m_proj_matrix = m;
  97. }
  98. mat4 const &Scene::GetViewMatrix(void)
  99. {
  100. return data->m_view_matrix;
  101. }
  102. mat4 const &Scene::GetProjMatrix(void)
  103. {
  104. return data->m_proj_matrix;
  105. }
  106. void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale)
  107. {
  108. Tile t;
  109. /* FIXME: this sorting only works for a 45-degree camera */
  110. t.prio = -pos.y - 2 * 32 * pos.z + (o ? 0 : 32);
  111. t.tileset = tileset;
  112. t.id = id;
  113. t.pos = pos;
  114. t.o = o;
  115. t.scale = scale;
  116. data->tiles.Push(t);
  117. }
  118. void Scene::Render() // XXX: rename to Blit()
  119. {
  120. /* Early exit if nothing needs to be rendered */
  121. if (!data->tiles.Count())
  122. return;
  123. if (!data->m_shader)
  124. data->m_shader = Shader::Create(lolfx_tile);
  125. #if 0
  126. // Randomise, then sort.
  127. for (int i = 0; i < data->tiles.Count(); i++)
  128. {
  129. Tile tmp = data->tiles[i];
  130. int j = rand() % data->tiles.Count();
  131. data->tiles[i] = data->tiles[j];
  132. data->tiles[j] = tmp;
  133. }
  134. #endif
  135. qsort(&data->tiles[0], data->tiles.Count(),
  136. sizeof(Tile), SceneData::Compare);
  137. // XXX: debug stuff
  138. data->m_model_matrix = mat4::translate(320.0f, 240.0f, 0.0f);
  139. #if 0
  140. static float f = 0.0f;
  141. f += 0.01f;
  142. data->m_model_matrix *= mat4::rotate(6.0f * sinf(f), 1.0f, 0.0f, 0.0f);
  143. data->m_model_matrix *= mat4::rotate(17.0f * cosf(f), 0.0f, 0.0f, 1.0f);
  144. #endif
  145. data->m_model_matrix *= mat4::translate(-320.0f, -240.0f, 0.0f);
  146. // XXX: end of debug stuff
  147. ShaderUniform uni_mat, uni_tex;
  148. ShaderAttrib attr_pos, attr_tex;
  149. attr_pos = data->m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0);
  150. attr_tex = data->m_shader->GetAttribLocation("in_TexCoord", VertexUsage::TexCoord, 0);
  151. data->m_shader->Bind();
  152. uni_mat = data->m_shader->GetUniformLocation("proj_matrix");
  153. data->m_shader->SetUniform(uni_mat, data->m_proj_matrix);
  154. uni_mat = data->m_shader->GetUniformLocation("view_matrix");
  155. data->m_shader->SetUniform(uni_mat, data->m_view_matrix);
  156. uni_mat = data->m_shader->GetUniformLocation("model_matrix");
  157. data->m_shader->SetUniform(uni_mat, data->m_model_matrix);
  158. #if defined USE_D3D9 || defined _XBOX
  159. #else
  160. uni_tex = data->m_shader->GetUniformLocation("in_Texture");
  161. data->m_shader->SetUniform(uni_tex, 0);
  162. #if !defined HAVE_GLES_2X
  163. glEnable(GL_TEXTURE_2D);
  164. #endif
  165. glEnable(GL_DEPTH_TEST);
  166. glDepthFunc(GL_LEQUAL);
  167. #if defined HAVE_GL_2X && !defined __APPLE__
  168. glEnable(GL_ALPHA_TEST);
  169. glAlphaFunc(GL_GEQUAL, 0.01f);
  170. #endif
  171. glEnable(GL_BLEND);
  172. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  173. #endif
  174. for (int buf = 0, i = 0, n; i < data->tiles.Count(); i = n, buf += 2)
  175. {
  176. /* Count how many quads will be needed */
  177. for (n = i + 1; n < data->tiles.Count(); n++)
  178. if (data->tiles[i].tileset != data->tiles[n].tileset)
  179. break;
  180. /* Create a vertex array object */
  181. VertexBuffer *vb1 = new VertexBuffer(6 * 3 * (n - i) * sizeof(float));
  182. float *vertex = (float *)vb1->Lock(0, 0);
  183. VertexBuffer *vb2 = new VertexBuffer(6 * 2 * (n - i) * sizeof(float));
  184. float *texture = (float *)vb2->Lock(0, 0);
  185. data->bufs.Push(vb1);
  186. data->bufs.Push(vb2);
  187. for (int j = i; j < n; j++)
  188. {
  189. data->tiles[i].tileset->BlitTile(data->tiles[j].id,
  190. data->tiles[j].pos, data->tiles[j].o,
  191. data->tiles[j].scale,
  192. vertex + 18 * (j - i), texture + 12 * (j - i));
  193. }
  194. vb1->Unlock();
  195. vb2->Unlock();
  196. /* Bind texture */
  197. data->tiles[i].tileset->Bind();
  198. /* Bind vertex and texture coordinate buffers */
  199. data->m_vdecl->Bind();
  200. data->m_vdecl->SetStream(vb1, attr_pos);
  201. data->m_vdecl->SetStream(vb2, attr_tex);
  202. /* Draw arrays */
  203. data->m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 2);
  204. data->m_vdecl->Unbind();
  205. data->tiles[i].tileset->Unbind();
  206. }
  207. data->tiles.Empty();
  208. data->m_shader->Unbind();
  209. #if defined USE_D3D9 || defined _XBOX
  210. /* TODO */
  211. #else
  212. #if !defined HAVE_GLES_2X
  213. glDisable(GL_TEXTURE_2D);
  214. #endif
  215. glDisable(GL_DEPTH_TEST);
  216. #if defined HAVE_GL_2X && !defined __APPLE__
  217. glDisable(GL_ALPHA_TEST);
  218. #endif
  219. glDisable(GL_BLEND);
  220. #endif
  221. }
  222. } /* namespace lol */