Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

344 рядки
9.6 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2019 Sam Hocevar <sam@hocevar.net>
  5. // © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
  6. //
  7. // Lol Engine is free software. It comes without any warranty, to
  8. // the extent permitted by applicable law. You can redistribute it
  9. // and/or modify it under the terms of the Do What the Fuck You Want
  10. // to Public License, Version 2, as published by the WTFPL Task Force.
  11. // See http://www.wtfpl.net/ for more details.
  12. //
  13. #pragma once
  14. //
  15. // The Scene class
  16. // ---------------
  17. //
  18. #include <memory>
  19. #include <cstdint>
  20. #include "tileset.h"
  21. #include "light.h"
  22. #include "camera.h"
  23. #include "mesh/mesh.h"
  24. #include <lol/gpu/renderer.h>
  25. #include <lol/base/thread.h>
  26. #define LOL_MAX_LIGHT_COUNT 8
  27. namespace lol
  28. {
  29. //-----------------------------------------------------------------------------
  30. class PrimitiveSource
  31. {
  32. friend class Scene;
  33. public:
  34. PrimitiveSource() { }
  35. virtual ~PrimitiveSource() { }
  36. virtual void Render(Scene& scene);
  37. private:
  38. };
  39. /*
  40. * A quick and dirty Tile structure for 2D blits
  41. */
  42. struct Tile
  43. {
  44. mat4 m_model;
  45. TileSet *m_tileset;
  46. int m_id;
  47. };
  48. class PrimitiveRenderer
  49. {
  50. friend class Scene;
  51. public:
  52. PrimitiveRenderer() { }
  53. virtual ~PrimitiveRenderer() { }
  54. virtual void Render(Scene& scene, std::shared_ptr<PrimitiveSource> primitive);
  55. private:
  56. bool m_fire_and_forget = false;
  57. };
  58. class SceneDisplay
  59. {
  60. friend class Scene;
  61. public:
  62. SceneDisplay() { }
  63. virtual ~SceneDisplay() { }
  64. /* pos/size/... methods */
  65. virtual void set_resolution(ivec2 resolution) { UNUSED(resolution); }
  66. virtual ivec2 resolution() const { return ivec2(0); }
  67. virtual void SetPosition(ivec2 position) { UNUSED(position); }
  68. /* TODO: Should that be there or in Video ? */
  69. static void Add(SceneDisplay* display);
  70. static int GetCount();
  71. static SceneDisplay* GetDisplay(int index = 0);
  72. static void DestroyAll();
  73. /* Implement these in the platform section */
  74. static int GetPhysicalCount();
  75. static const char* GetPhysicalName(int index = 0);
  76. //protected:
  77. virtual void Enable();
  78. virtual void Disable();
  79. };
  80. class Scene
  81. {
  82. friend class Video;
  83. private:
  84. static array<Scene*> g_scenes;
  85. Scene(ivec2 size);
  86. ~Scene();
  87. public:
  88. static void AddNew(ivec2 size);
  89. private: //Private because I don't know if we should have it
  90. static void DestroyScene(Scene* scene);
  91. private:
  92. static void DestroyAll();
  93. public:
  94. static int GetCount();
  95. static bool IsReady(int index = 0);
  96. static Scene& GetScene(int index = 0);
  97. public:
  98. //TODO: don't like the name
  99. void Link(entity* entity);
  100. bool IsRelevant(entity* entity);
  101. public:
  102. Camera* GetCamera(int cam_idx = -1);
  103. int PushCamera(Camera *cam);
  104. void PopCamera(Camera *cam);
  105. void SetTileCam(int cam_idx);
  106. void Reset();
  107. std::shared_ptr<Renderer> get_renderer() { return m_renderer; }
  108. /* ============================== */
  109. # define _KEY_IDX (uintptr_t)key /* TOUKY: I don't like that. hash should be fixed to handle these custom stuff */
  110. /* ============================== */
  111. private:
  112. int HasPrimitiveSource(uintptr_t key);
  113. int AddPrimitiveSource(uintptr_t key, std::shared_ptr<class PrimitiveSource> source);
  114. void SetPrimitiveSource(int index, uintptr_t key, std::shared_ptr<class PrimitiveSource> source);
  115. void ReleasePrimitiveSource(int index, uintptr_t key);
  116. void ReleaseAllPrimitiveSources(uintptr_t key);
  117. public:
  118. /* === Primitive source stuff === */
  119. /* Returns the number of primitive source set to the given entity */
  120. template <typename T>
  121. int HasPrimitiveSource(T* key)
  122. {
  123. ASSERT(key);
  124. return HasPrimitiveSource(_KEY_IDX);
  125. }
  126. /* Add a primitive sources linked to the given entity
  127. * Returns the slot number */
  128. template <typename T>
  129. int AddPrimitiveSource(T* key, std::shared_ptr<class PrimitiveSource> source)
  130. {
  131. ASSERT(key);
  132. return AddPrimitiveSource(_KEY_IDX, source);
  133. }
  134. /* Update the primitive source at index linked to the given entity
  135. * Deletes the old one
  136. * The slot is kept even if source == nullptr */
  137. template <typename T>
  138. void SetPrimitiveSource(int index, T* key, std::shared_ptr<class PrimitiveSource> source)
  139. {
  140. ASSERT(key);
  141. SetPrimitiveSource(index, _KEY_IDX, source);
  142. }
  143. /* Remove primitive source at index set to the given entity */
  144. template <typename T>
  145. void ReleasePrimitiveSource(int index, T* key)
  146. {
  147. ASSERT(key);
  148. ReleasePrimitiveSource(index, _KEY_IDX);
  149. }
  150. /* Remove all primitive source set to the given entity */
  151. template <typename T>
  152. void ReleaseAllPrimitiveSources(T* key)
  153. {
  154. ASSERT(key);
  155. ReleaseAllPrimitiveSources(_KEY_IDX);
  156. }
  157. private:
  158. int HasPrimitiveRenderer(uintptr_t key);
  159. void AddPrimitiveRenderer(uintptr_t key, std::shared_ptr<class PrimitiveRenderer> renderer);
  160. void SetPrimitiveRenderer(int index, uintptr_t key, std::shared_ptr<class PrimitiveRenderer> renderer);
  161. void ReleasePrimitiveRenderer(int index, uintptr_t key);
  162. void ReleaseAllPrimitiveRenderers(uintptr_t key);
  163. public:
  164. /* === Primitive renderer stuff === */
  165. /* Returns the number of primitive renderer set to the given entity */
  166. template <typename T>
  167. int HasPrimitiveRenderer(T* key)
  168. {
  169. ASSERT(key);
  170. return HasPrimitiveRenderer(_KEY_IDX);
  171. }
  172. /* Add a primitive renderer linked to the given entity
  173. * The primitive is considered as Fire&Forget and
  174. * will be destroyed at the end of the frame */
  175. template <typename T>
  176. void AddPrimitiveRenderer(T* key, std::shared_ptr<class PrimitiveRenderer> renderer)
  177. {
  178. ASSERT(key);
  179. AddPrimitiveRenderer(_KEY_IDX, renderer);
  180. }
  181. /* Update the primitive renderer linked to the given entity
  182. * Deletes the old one
  183. * Will assert if renderer == nullptr */
  184. template <typename T>
  185. void SetPrimitiveRenderer(int index, T* key, std::shared_ptr<class PrimitiveRenderer> renderer)
  186. {
  187. ASSERT(key && renderer);
  188. SetPrimitiveRenderer(index, _KEY_IDX, renderer);
  189. }
  190. /* Remove primitive renderer at index set to the given entity */
  191. template <typename T>
  192. void ReleasePrimitiveRenderer(int index, T* key)
  193. {
  194. ASSERT(key);
  195. ReleasePrimitiveRenderer(index, _KEY_IDX);
  196. }
  197. /* Remove all primitive renderer set to the given entity */
  198. template <typename T>
  199. void ReleaseAllPrimitiveRenderers(T* key)
  200. {
  201. ASSERT(key);
  202. ReleaseAllPrimitiveRenderers(_KEY_IDX);
  203. }
  204. /* ============================== */
  205. # undef _KEY_IDX /* (uintptr_t)key *//* TOUKY: I don't like that. hash should be fixed to handle these custom stuff */
  206. /* ============================== */
  207. /* FIXME: this should be deprecated -- it doesn't really match
  208. * the architecture we want to build */
  209. void AddTile(TileSet *tileset, int id, vec3 pos, vec2 scale, float radians);
  210. void AddTile(TileSet *tileset, int id, mat4 model);
  211. public:
  212. void AddLine(vec3 a, vec3 b, vec4 color);
  213. void AddLine(vec3 a, vec3 b, vec4 color, float duration, int mask);
  214. void AddLight(Light *light);
  215. array<Light *> const &GetLights();
  216. /* === Render stuff === */
  217. void SetDisplay(SceneDisplay* display);
  218. void EnableDisplay();
  219. void DisableDisplay();
  220. void resize(ivec2 size);
  221. void pre_render(float seconds);
  222. void render(float seconds);
  223. void post_render(float seconds);
  224. private:
  225. void render_primitives();
  226. void render_tiles();
  227. void render_lines(float seconds);
  228. ivec2 m_size, m_wanted_size;
  229. std::shared_ptr<Renderer> m_renderer;
  230. //
  231. // The old SceneData stuff
  232. //
  233. /* Mask ID */
  234. /* TODO: Do a mask class that handles more than 64 slots */
  235. static uint64_t g_used_id;
  236. uint64_t m_mask_id = 0;
  237. /* Scene display: if none has been set to the scene,
  238. * the default one created by the app will be used */
  239. SceneDisplay* m_display = nullptr;
  240. /** Render buffers: where to render to. */
  241. std::shared_ptr<Framebuffer> m_renderbuffer[4];
  242. struct postprocess
  243. {
  244. std::shared_ptr<Shader> blit_shader, pp_shader;
  245. std::shared_ptr<VertexBuffer> quad_vbo;
  246. std::shared_ptr<VertexDeclaration> quad_vdecl;
  247. ShaderUniform m_buffer_uni[2][3];
  248. ShaderAttrib blit_pos_attr, pp_pos_attr;
  249. }
  250. m_pp;
  251. /* Sources are shared by all scenes.
  252. * Renderers are scene-dependent. They get the primitive in the identical
  253. * slot to render with the given scene.
  254. * Primitives and renderers will be kept until:
  255. * - Updated by entity
  256. * - Marked Fire&Forget
  257. * - Scene is destroyed */
  258. std::map<uintptr_t, array<std::shared_ptr<PrimitiveRenderer>>> m_prim_renderers;
  259. static std::map<uintptr_t, array<std::shared_ptr<PrimitiveSource>>> g_prim_sources;
  260. static mutex g_prim_mutex;
  261. Camera *m_default_cam;
  262. array<Camera *> m_camera_stack;
  263. /* Old line API <P0, P1, COLOR, TIME, MASK> */
  264. struct line_api
  265. {
  266. //float m_duration, m_segment_size;
  267. //vec4 m_color;
  268. array<vec3, vec3, vec4, float, int, bool, bool> m_lines;
  269. int /*m_mask,*/ m_debug_mask;
  270. std::shared_ptr<Shader> m_shader;
  271. std::shared_ptr<VertexDeclaration> m_vdecl;
  272. }
  273. m_line_api;
  274. /* The old tiles API */
  275. struct tile_api
  276. {
  277. int m_cam;
  278. array<Tile> m_tiles;
  279. array<Tile> m_palettes;
  280. array<Light *> m_lights;
  281. std::shared_ptr<Shader> m_shader;
  282. std::shared_ptr<Shader> m_palette_shader;
  283. std::shared_ptr<VertexDeclaration> m_vdecl;
  284. array<std::shared_ptr<VertexBuffer>> m_bufs;
  285. }
  286. m_tile_api;
  287. };
  288. } /* namespace lol */