Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 

702 rindas
21 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2014 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. #include <lol/engine-internal.h>
  11. #include <cstdlib>
  12. #if defined(_WIN32)
  13. # define WIN32_LEAN_AND_MEAN 1
  14. # include <windows.h>
  15. #endif
  16. #include "lolgl.h"
  17. LOLFX_RESOURCE_DECLARE(tile);
  18. LOLFX_RESOURCE_DECLARE(palette);
  19. LOLFX_RESOURCE_DECLARE(line);
  20. namespace lol
  21. {
  22. /*
  23. * The global g_scenes object, initialised by Video::Init
  24. */
  25. array<Scene*> Scene::g_scenes;
  26. /*
  27. * A quick and dirty Tile structure for 2D blits
  28. */
  29. struct Tile
  30. {
  31. TileSet *tileset;
  32. uint32_t prio;
  33. vec3 pos;
  34. vec2 scale;
  35. float angle;
  36. int id, o;
  37. };
  38. /*
  39. * Scene implementation class
  40. */
  41. void PrimitiveSource::Render(Scene& scene) { UNUSED(scene); }
  42. void PrimitiveRenderer::Render(Scene& scene, PrimitiveSource* primitive)
  43. {
  44. UNUSED(scene);
  45. UNUSED(primitive);
  46. }
  47. /*
  48. * Scene implementation class
  49. */
  50. class SceneData
  51. {
  52. friend class Scene;
  53. private:
  54. SceneData()
  55. {
  56. /* TODO: FIX THAT */
  57. ASSERT(!(m_used_id & ((uint64_t)1 << 63)), "Too many scenes !!!!");
  58. m_mask_id = m_used_id;
  59. m_used_id = m_used_id << 1;
  60. }
  61. /* Mask ID */
  62. /* TODO: Do a mask class that handles more than 64 slots */
  63. static uint64_t m_used_id;
  64. uint64_t m_mask_id = 0;
  65. /* New scenegraph */
  66. array<PrimitiveSource*> m_primitives;
  67. /* Primitives are shared by all scenes.
  68. * Renderers are scene-dependent. They get the primitive in the identical slot to render with the given scene
  69. * Primitives and renderers will be kept until:
  70. * - Updated by entity
  71. * - Scene is destroyed */
  72. map<uintptr_t, array<PrimitiveRenderer*> > m_prim_renderers;
  73. static map<uintptr_t, array<PrimitiveSource*> > m_prim_sources;
  74. static mutex m_prim_mutex;
  75. /* Old API <P0, P1, COLOR, TIME, MASK> */
  76. float m_new_line_time;
  77. int m_new_line_mask;
  78. float m_new_line_segment_size;
  79. vec4 m_new_line_color;
  80. array<vec3, vec3, vec4, float, int, bool, bool> m_lines;
  81. int m_debug_mask;
  82. Shader *m_line_shader;
  83. VertexDeclaration *m_line_vdecl;
  84. int m_tile_cam;
  85. array<Tile> m_tiles;
  86. array<Tile> m_palettes;
  87. array<Light *> m_lights;
  88. Shader *m_tile_shader;
  89. Shader *m_palette_shader;
  90. VertexDeclaration *m_tile_vdecl;
  91. array<VertexBuffer *> m_tile_bufs;
  92. Camera *m_default_cam;
  93. array<Camera *> m_camera_stack;
  94. };
  95. uint64_t SceneData::m_used_id = 1;
  96. map<uintptr_t, array<PrimitiveSource*> > SceneData::m_prim_sources;
  97. mutex SceneData::m_prim_mutex;
  98. /*
  99. * Public Scene class
  100. */
  101. Scene::Scene(ivec2 size)
  102. : data(new SceneData())
  103. {
  104. /* Create a default orthographic camera, in case the user doesn’t. */
  105. data->m_default_cam = new Camera();
  106. mat4 proj = mat4::ortho(0.f, (float)size.x, 0.f, (float)size.y, -1000.f, 1000.f);
  107. data->m_default_cam->SetProjection(proj);
  108. PushCamera(data->m_default_cam);
  109. data->m_tile_cam = -1;
  110. data->m_tile_shader = 0;
  111. data->m_palette_shader = 0;
  112. data->m_tile_vdecl = new VertexDeclaration(VertexStream<vec3>(VertexUsage::Position),
  113. VertexStream<vec2>(VertexUsage::TexCoord));
  114. data->m_line_shader = 0;
  115. data->m_line_vdecl = new VertexDeclaration(VertexStream<vec4,vec4>(VertexUsage::Position, VertexUsage::Color));
  116. data->m_debug_mask = 1;
  117. SetLineTime();
  118. SetLineMask();
  119. SetLineSegmentSize();
  120. SetLineColor();
  121. }
  122. //-----------------------------------------------------------------------------
  123. Scene::~Scene()
  124. {
  125. PopCamera(data->m_default_cam);
  126. /* FIXME: this must be done while the GL context is still active.
  127. * Change the code architecture to make sure of that. */
  128. /* FIXME: also, make sure we do not add code to Reset() that will
  129. * reallocate stuff */
  130. Reset();
  131. delete data->m_line_vdecl;
  132. delete data->m_tile_vdecl;
  133. delete data;
  134. }
  135. //-----------------------------------------------------------------------------
  136. void Scene::AddNew(ivec2 size)
  137. {
  138. Scene::g_scenes << new Scene(size);
  139. }
  140. void Scene::DestroyScene(Scene* scene)
  141. {
  142. Scene::g_scenes.remove_item(scene);
  143. delete scene;
  144. }
  145. void Scene::DestroyAll()
  146. {
  147. while (Scene::g_scenes.count())
  148. delete Scene::g_scenes.pop();
  149. }
  150. ptrdiff_t Scene::GetCount()
  151. {
  152. return g_scenes.count();
  153. }
  154. //-----------------------------------------------------------------------------
  155. bool Scene::IsReady(ptrdiff_t index)
  156. {
  157. return 0 <= index && index < g_scenes.count() && !!g_scenes[index];
  158. }
  159. //-----------------------------------------------------------------------------
  160. Scene& Scene::GetScene(ptrdiff_t index)
  161. {
  162. ASSERT(0 <= index && index < g_scenes.count() && !!g_scenes[index], "Trying to get a non-existent scene");
  163. return *g_scenes[index];
  164. }
  165. //-----------------------------------------------------------------------------
  166. void Scene::Link(Entity* entity)
  167. {
  168. entity->m_scene_mask |= data->m_mask_id;
  169. }
  170. //-----------------------------------------------------------------------------
  171. bool Scene::IsRelevant(Entity* entity)
  172. {
  173. return !!(entity->m_scene_mask & data->m_mask_id);
  174. }
  175. //-----------------------------------------------------------------------------
  176. Camera* Scene::GetCamera(int cam_idx)
  177. {
  178. ASSERT(!!data, "Trying to access a non-ready scene");
  179. return (0 <= cam_idx && cam_idx < data->m_camera_stack.Count()) ?
  180. data->m_camera_stack[cam_idx] :
  181. data->m_camera_stack.Last();
  182. }
  183. //-----------------------------------------------------------------------------
  184. int Scene::PushCamera(Camera *cam)
  185. {
  186. ASSERT(!!data, "Trying to access a non-ready scene");
  187. Ticker::Ref(cam);
  188. data->m_camera_stack.Push(cam);
  189. return (int)data->m_camera_stack.Count() - 1;
  190. }
  191. //-----------------------------------------------------------------------------
  192. void Scene::PopCamera(Camera *cam)
  193. {
  194. ASSERT(!!data, "Trying to access a non-ready scene");
  195. /* Parse from the end because that’s probably where we’ll find
  196. * our camera first. */
  197. for (ptrdiff_t i = data->m_camera_stack.Count(); i--;)
  198. {
  199. if (data->m_camera_stack[i] == cam)
  200. {
  201. Ticker::Unref(cam);
  202. data->m_camera_stack.Remove(i);
  203. return;
  204. }
  205. }
  206. ASSERT(false, "trying to pop a nonexistent camera from the scene");
  207. }
  208. //-----------------------------------------------------------------------------
  209. void Scene::SetTileCam(int cam_idx)
  210. {
  211. ASSERT(!!data, "Trying to access a non-ready scene");
  212. data->m_tile_cam = cam_idx;
  213. }
  214. //-----------------------------------------------------------------------------
  215. void Scene::Reset()
  216. {
  217. ASSERT(!!data, "Trying to access a non-ready scene");
  218. /* New scenegraph: Release fire&forget primitives */
  219. array<uintptr_t> keys = data->m_prim_renderers.keys();
  220. for (uintptr_t key : keys)
  221. {
  222. for (ptrdiff_t idx = 0; idx < data->m_prim_renderers[key].count(); ++idx)
  223. if (data->m_prim_renderers[key][idx]->m_fire_and_forget)
  224. ReleasePrimitiveRenderer(idx--, key);
  225. }
  226. for (int i = 0; i < data->m_tile_bufs.Count(); i++)
  227. delete data->m_tile_bufs[i];
  228. data->m_tile_bufs.Empty();
  229. data->m_lights.Empty();
  230. for (int i = 0; i < data->m_primitives.count(); i++)
  231. delete data->m_primitives[i];
  232. data->m_primitives.Empty();
  233. }
  234. //-----------------------------------------------------------------------------
  235. void Scene::AddPrimitive(PrimitiveSource* primitive)
  236. {
  237. data->m_primitives.Push(primitive);
  238. }
  239. //---- Primitive source stuff -------------------------------------------------
  240. ptrdiff_t Scene::HasPrimitiveSource(uintptr_t key)
  241. {
  242. ptrdiff_t count;
  243. SceneData::m_prim_mutex.lock();
  244. {
  245. count = SceneData::m_prim_sources[key].count();
  246. }
  247. SceneData::m_prim_mutex.unlock();
  248. return count;
  249. }
  250. ptrdiff_t Scene::AddPrimitiveSource(uintptr_t key, PrimitiveSource* source)
  251. {
  252. ptrdiff_t count;
  253. SceneData::m_prim_mutex.lock();
  254. {
  255. count = SceneData::m_prim_sources[key].count();
  256. SceneData::m_prim_sources[key].push(source);
  257. }
  258. SceneData::m_prim_mutex.unlock();
  259. return count;
  260. }
  261. void Scene::SetPrimitiveSource(ptrdiff_t index, uintptr_t key, PrimitiveSource* source)
  262. {
  263. ASSERT(source);
  264. ASSERT(index < 0);
  265. PrimitiveSource* old = nullptr;
  266. SceneData::m_prim_mutex.lock();
  267. {
  268. if (index < SceneData::m_prim_sources[key].count())
  269. old = SceneData::m_prim_sources[key][index];
  270. else
  271. SceneData::m_prim_sources[key].resize(index + 1);
  272. SceneData::m_prim_sources[key][index] = source;
  273. }
  274. SceneData::m_prim_mutex.unlock();
  275. //Delete old AFTER having released the lock
  276. if (old) delete old;
  277. }
  278. void Scene::ReleasePrimitiveSource(ptrdiff_t index, uintptr_t key)
  279. {
  280. PrimitiveSource* old = nullptr;
  281. SceneData::m_prim_mutex.lock();
  282. {
  283. ASSERT(0 <= index && index < SceneData::m_prim_sources[key].count());
  284. old = SceneData::m_prim_sources[key][index];
  285. SceneData::m_prim_sources[key].remove(index);
  286. }
  287. SceneData::m_prim_mutex.unlock();
  288. //Delete old AFTER having released the lock
  289. if (old) delete old;
  290. }
  291. void Scene::ReleaseAllPrimitiveSource(uintptr_t key)
  292. {
  293. array<PrimitiveSource*> oldies;
  294. SceneData::m_prim_mutex.lock();
  295. {
  296. oldies.reserve(SceneData::m_prim_sources[key].count());
  297. for (PrimitiveSource* source : SceneData::m_prim_sources[key])
  298. oldies << source;
  299. SceneData::m_prim_sources[key].empty();
  300. }
  301. SceneData::m_prim_mutex.unlock();
  302. //Delete oldies AFTER having released the lock
  303. for (PrimitiveSource* old : oldies)
  304. if (old) delete old;
  305. }
  306. //---- Primitive renderer stuff -----------------------------------------------
  307. ptrdiff_t Scene::HasPrimitiveRenderer(uintptr_t key)
  308. {
  309. return data->m_prim_renderers[key].count();
  310. }
  311. void Scene::AddPrimitiveRenderer(uintptr_t key, PrimitiveRenderer* renderer)
  312. {
  313. renderer->m_fire_and_forget = true;
  314. data->m_prim_renderers[key].push(renderer);
  315. }
  316. void Scene::SetPrimitiveRenderer(ptrdiff_t index, uintptr_t key, PrimitiveRenderer* renderer)
  317. {
  318. ASSERT(renderer);
  319. ASSERT(index < 0);
  320. if (index < data->m_prim_renderers[key].count())
  321. {
  322. ASSERT(data->m_prim_renderers[key][index]);
  323. delete data->m_prim_renderers[key][index];
  324. }
  325. else
  326. data->m_prim_renderers[key].resize(index + 1);
  327. data->m_prim_renderers[key][index] = renderer;
  328. }
  329. void Scene::ReleasePrimitiveRenderer(ptrdiff_t index, uintptr_t key)
  330. {
  331. ASSERT(0 <= index && index < data->m_prim_renderers[key].count());
  332. ASSERT(data->m_prim_renderers[key][index]);
  333. delete data->m_prim_renderers[key][index];
  334. data->m_prim_renderers[key].remove(index);
  335. }
  336. void Scene::ReleaseAllPrimitiveRenderer(uintptr_t key)
  337. {
  338. for (PrimitiveRenderer* renderer : data->m_prim_renderers[key])
  339. {
  340. ASSERT(renderer);
  341. delete renderer;
  342. }
  343. }
  344. //-----------------------------------------------------------------------------
  345. void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float angle)
  346. {
  347. ASSERT(id < tileset->GetTileCount());
  348. Tile t;
  349. /* FIXME: this sorting only works for a 45-degree camera */
  350. t.prio = (uint32_t)(-pos.y - (int)(2 * 32 * pos.z) + ((float)o ? 0 : 32));
  351. t.tileset = tileset;
  352. t.id = id;
  353. t.pos = pos;
  354. t.o = o;
  355. t.scale = scale;
  356. t.angle = angle;
  357. if (tileset->GetPalette())
  358. data->m_palettes.Push(t);
  359. else
  360. data->m_tiles.Push(t);
  361. }
  362. //-----------------------------------------------------------------------------
  363. void Scene::SetLineTime(float new_time)
  364. {
  365. ASSERT(!!data, "Trying to access a non-ready scene");
  366. data->m_new_line_time = new_time;
  367. }
  368. void Scene::SetLineMask(int new_mask)
  369. {
  370. ASSERT(!!data, "Trying to access a non-ready scene");
  371. data->m_new_line_mask = new_mask;
  372. }
  373. void Scene::SetLineSegmentSize(float new_segment_size)
  374. {
  375. ASSERT(!!data, "Trying to access a non-ready scene");
  376. data->m_new_line_segment_size = new_segment_size;
  377. }
  378. void Scene::SetLineColor(vec4 new_color)
  379. {
  380. ASSERT(!!data, "Trying to access a non-ready scene");
  381. data->m_new_line_color = new_color;
  382. }
  383. //-----------------------------------------------------------------------------
  384. float Scene::GetLineSegmentSize()
  385. {
  386. ASSERT(!!data, "Trying to access a non-ready scene");
  387. return data->m_new_line_segment_size;
  388. }
  389. vec4 Scene::GetLineColor()
  390. {
  391. ASSERT(!!data, "Trying to access a non-ready scene");
  392. return data->m_new_line_color;
  393. }
  394. //-----------------------------------------------------------------------------
  395. void Scene::AddLine(vec3 a, vec3 b, vec4 color)
  396. {
  397. ASSERT(!!data, "Trying to access a non-ready scene");
  398. data->m_lines.Push(a, b, color,
  399. data->m_new_line_time, data->m_new_line_mask, false, false);
  400. }
  401. //-----------------------------------------------------------------------------
  402. void Scene::AddLight(Light *l)
  403. {
  404. ASSERT(!!data, "Trying to access a non-ready scene");
  405. data->m_lights.Push(l);
  406. }
  407. //-----------------------------------------------------------------------------
  408. array<Light *> const &Scene::GetLights()
  409. {
  410. ASSERT(!!data, "Trying to access a non-ready scene");
  411. return data->m_lights;
  412. }
  413. //-----------------------------------------------------------------------------
  414. void Scene::RenderPrimitives()
  415. {
  416. ASSERT(!!data, "Trying to access a non-ready scene");
  417. /* TODO: this should be the main entry for rendering of all
  418. * primitives found in the scene graph. When we have one. */
  419. for (PrimitiveSource* p : data->m_primitives)
  420. {
  421. p->Render(*this);
  422. }
  423. /* new scenegraph */
  424. array<uintptr_t> keys = data->m_prim_renderers.keys();
  425. for (uintptr_t key : keys)
  426. {
  427. for (ptrdiff_t idx = 0; idx < data->m_prim_renderers[key].count(); ++idx)
  428. {
  429. /* TODO: Not sure if thread compliant */
  430. data->m_prim_renderers[key][idx]->Render(*this, idx < SceneData::m_prim_sources[key].count() ? SceneData::m_prim_sources[key][idx] : nullptr);
  431. }
  432. }
  433. }
  434. //-----------------------------------------------------------------------------
  435. void Scene::RenderTiles() // XXX: rename to Blit()
  436. {
  437. ASSERT(!!data, "Trying to access a non-ready scene");
  438. RenderContext rc;
  439. /* Early test if nothing needs to be rendered */
  440. if (!data->m_tiles.Count() && !data->m_palettes.Count())
  441. return;
  442. rc.SetDepthFunc(DepthFunc::LessOrEqual);
  443. rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha);
  444. rc.SetBlendEquation(BlendEquation::Add, BlendEquation::Max);
  445. rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f);
  446. #if defined USE_D3D9 || defined _XBOX
  447. /* TODO */
  448. #elif (defined USE_GLEW || defined HAVE_GL_2X) && !defined HAVE_GLES_2X
  449. glEnable(GL_TEXTURE_2D);
  450. #endif
  451. if (!data->m_tile_shader)
  452. data->m_tile_shader = Shader::Create(LOLFX_RESOURCE_NAME(tile));
  453. if (!data->m_palette_shader)
  454. data->m_palette_shader = Shader::Create(LOLFX_RESOURCE_NAME(palette));
  455. for (int p = 0; p < 2; p++)
  456. {
  457. Shader *shader = (p == 0) ? data->m_tile_shader : data->m_palette_shader;
  458. array<Tile>& tiles = (p == 0) ? data->m_tiles : data->m_palettes;
  459. if (tiles.Count() == 0)
  460. continue;
  461. ShaderUniform uni_mat, uni_tex, uni_pal, uni_texsize;
  462. ShaderAttrib attr_pos, attr_tex;
  463. attr_pos = shader->GetAttribLocation(VertexUsage::Position, 0);
  464. attr_tex = shader->GetAttribLocation(VertexUsage::TexCoord, 0);
  465. shader->Bind();
  466. uni_mat = shader->GetUniformLocation("u_projection");
  467. shader->SetUniform(uni_mat, GetCamera(data->m_tile_cam)->GetProjection());
  468. uni_mat = shader->GetUniformLocation("u_view");
  469. shader->SetUniform(uni_mat, GetCamera(data->m_tile_cam)->GetView());
  470. uni_mat = shader->GetUniformLocation("u_model");
  471. shader->SetUniform(uni_mat, mat4(1.f));
  472. uni_tex = shader->GetUniformLocation("u_texture");
  473. uni_pal = data->m_palette_shader->GetUniformLocation("u_palette");
  474. uni_texsize = shader->GetUniformLocation("u_texsize");
  475. for (int buf = 0, i = 0, n; i < tiles.Count(); i = n, buf += 2)
  476. {
  477. /* Count how many quads will be needed */
  478. for (n = i + 1; n < tiles.Count(); n++)
  479. if (tiles[i].tileset != tiles[n].tileset)
  480. break;
  481. /* Create a vertex array object */
  482. VertexBuffer *vb1 = new VertexBuffer(6 * (n - i) * sizeof(vec3));
  483. vec3 *vertex = (vec3 *)vb1->Lock(0, 0);
  484. VertexBuffer *vb2 = new VertexBuffer(6 * (n - i) * sizeof(vec2));
  485. vec2 *texture = (vec2 *)vb2->Lock(0, 0);
  486. data->m_tile_bufs.Push(vb1);
  487. data->m_tile_bufs.Push(vb2);
  488. for (int j = i; j < n; j++)
  489. {
  490. tiles[i].tileset->BlitTile(tiles[j].id,
  491. tiles[j].pos, tiles[j].o,
  492. tiles[j].scale, tiles[j].angle,
  493. vertex + 6 * (j - i), texture + 6 * (j - i));
  494. }
  495. vb1->Unlock();
  496. vb2->Unlock();
  497. /* Bind texture */
  498. if (tiles[i].tileset->GetPalette())
  499. {
  500. if (tiles[i].tileset->GetTexture())
  501. shader->SetUniform(uni_tex, tiles[i].tileset->GetTexture()->GetTextureUniform(), 0);
  502. if (tiles[i].tileset->GetPalette()->GetTexture())
  503. shader->SetUniform(uni_pal, tiles[i].tileset->GetPalette()->GetTexture()->GetTextureUniform(), 1);
  504. }
  505. else
  506. {
  507. shader->SetUniform(uni_tex, 0);
  508. if (tiles[i].tileset->GetTexture())
  509. shader->SetUniform(uni_tex, tiles[i].tileset->GetTexture()->GetTextureUniform(), 0);
  510. tiles[i].tileset->Bind();
  511. }
  512. shader->SetUniform(uni_texsize,
  513. (vec2)tiles[i].tileset->GetTextureSize());
  514. /* Bind vertex and texture coordinate buffers */
  515. data->m_tile_vdecl->Bind();
  516. data->m_tile_vdecl->SetStream(vb1, attr_pos);
  517. data->m_tile_vdecl->SetStream(vb2, attr_tex);
  518. /* Draw arrays */
  519. data->m_tile_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6);
  520. data->m_tile_vdecl->Unbind();
  521. tiles[i].tileset->Unbind();
  522. }
  523. tiles.Empty();
  524. shader->Unbind();
  525. }
  526. #if defined USE_D3D9 || defined _XBOX
  527. /* TODO */
  528. #elif (defined USE_GLEW || defined HAVE_GL_2X) && !defined HAVE_GLES_2X
  529. glDisable(GL_TEXTURE_2D);
  530. #endif
  531. }
  532. //-----------------------------------------------------------------------------
  533. void Scene::RenderLines(float seconds) // XXX: rename to Blit()
  534. {
  535. ASSERT(!!data, "Trying to access a non-ready scene");
  536. RenderContext rc;
  537. if (!data->m_lines.Count())
  538. return;
  539. rc.SetDepthFunc(DepthFunc::LessOrEqual);
  540. rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha);
  541. rc.SetBlendEquation(BlendEquation::Add, BlendEquation::Max);
  542. rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f);
  543. int linecount = (int)data->m_lines.Count();
  544. if (!data->m_line_shader)
  545. data->m_line_shader = Shader::Create(LOLFX_RESOURCE_NAME(line));
  546. array<vec4, vec4, vec4, vec4> buff;
  547. buff.Resize(linecount);
  548. int real_linecount = 0;
  549. mat4 const inv_view_proj = inverse(GetCamera()->GetProjection() * GetCamera()->GetView());
  550. for (int i = 0; i < linecount; i++)
  551. {
  552. if (data->m_lines[i].m5 & data->m_debug_mask)
  553. {
  554. buff[real_linecount].m1 = vec4(data->m_lines[i].m1, (float)data->m_lines[i].m6);
  555. buff[real_linecount].m2 = data->m_lines[i].m3;
  556. buff[real_linecount].m3 = vec4(data->m_lines[i].m2, (float)data->m_lines[i].m7);
  557. buff[real_linecount].m4 = data->m_lines[i].m3;
  558. real_linecount++;
  559. }
  560. data->m_lines[i].m4 -= seconds;
  561. if (data->m_lines[i].m4 < 0.f)
  562. {
  563. data->m_lines.RemoveSwap(i--);
  564. linecount--;
  565. }
  566. }
  567. VertexBuffer *vb = new VertexBuffer(buff.Bytes());
  568. float *vertex = (float *)vb->Lock(0, 0);
  569. memcpy(vertex, buff.Data(), buff.Bytes());
  570. vb->Unlock();
  571. data->m_line_shader->Bind();
  572. ShaderUniform uni_mat, uni_tex;
  573. ShaderAttrib attr_pos, attr_col;
  574. attr_pos = data->m_line_shader->GetAttribLocation(VertexUsage::Position, 0);
  575. attr_col = data->m_line_shader->GetAttribLocation(VertexUsage::Color, 0);
  576. data->m_line_shader->Bind();
  577. uni_mat = data->m_line_shader->GetUniformLocation("u_projection");
  578. data->m_line_shader->SetUniform(uni_mat, GetCamera()->GetProjection());
  579. uni_mat = data->m_line_shader->GetUniformLocation("u_view");
  580. data->m_line_shader->SetUniform(uni_mat, GetCamera()->GetView());
  581. data->m_line_vdecl->Bind();
  582. data->m_line_vdecl->SetStream(vb, attr_pos, attr_col);
  583. data->m_line_vdecl->DrawElements(MeshPrimitive::Lines, 0, 2 * real_linecount);
  584. data->m_line_vdecl->Unbind();
  585. data->m_line_shader->Unbind();
  586. //data->m_lines.Empty();
  587. delete vb;
  588. }
  589. } /* namespace lol */