|
- //
- // Lol Engine
- //
- // Copyright © 2010—2019 Sam Hocevar <sam@hocevar.net>
- // © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
- //
- // Lol Engine is free software. It comes without any warranty, to
- // the extent permitted by applicable law. You can redistribute it
- // and/or modify it under the terms of the Do What the Fuck You Want
- // to Public License, Version 2, as published by the WTFPL Task Force.
- // See http://www.wtfpl.net/ for more details.
- //
-
- #pragma once
-
- //
- // The Scene class
- // ---------------
- //
-
- #include <memory>
- #include <cstdint>
-
- #include "tileset.h"
- #include "light.h"
- #include "camera.h"
- #include "mesh/mesh.h"
- #include <lol/gpu/renderer.h>
-
- #define LOL_MAX_LIGHT_COUNT 8
-
- namespace lol
- {
-
- //-----------------------------------------------------------------------------
- class PrimitiveSource
- {
- friend class Scene;
-
- public:
- PrimitiveSource() { }
- virtual ~PrimitiveSource() { }
- virtual void Render(Scene& scene);
-
- private:
- };
-
- /*
- * A quick and dirty Tile structure for 2D blits
- */
-
- struct Tile
- {
- mat4 m_model;
- TileSet *m_tileset;
- int m_id;
- };
-
- class PrimitiveRenderer
- {
- friend class Scene;
-
- public:
- PrimitiveRenderer() { }
- virtual ~PrimitiveRenderer() { }
- virtual void Render(Scene& scene, std::shared_ptr<PrimitiveSource> primitive);
-
- private:
- bool m_fire_and_forget = false;
- };
-
- class SceneDisplay
- {
- friend class Scene;
-
- public:
- SceneDisplay() { }
- virtual ~SceneDisplay() { }
-
- /* pos/size/... methods */
- virtual void set_resolution(ivec2 resolution) { UNUSED(resolution); }
- virtual ivec2 resolution() const { return ivec2(0); }
-
- virtual void SetPosition(ivec2 position) { UNUSED(position); }
-
- /* TODO: Should that be there or in Video ? */
- static void Add(SceneDisplay* display);
- static int GetCount();
- static SceneDisplay* GetDisplay(int index = 0);
- static void DestroyAll();
-
- /* Implement these in the platform section */
- static int GetPhysicalCount();
- static const char* GetPhysicalName(int index = 0);
-
- //protected:
- virtual void Enable();
- virtual void Disable();
- };
-
- class Scene
- {
- friend class Video;
-
- private:
- static array<Scene*> g_scenes;
-
- Scene(ivec2 size);
- ~Scene();
-
- public:
- static void AddNew(ivec2 size);
- private: //Private because I don't know if we should have it
- static void DestroyScene(Scene* scene);
- private:
- static void DestroyAll();
- public:
- static int GetCount();
- static bool IsReady(int index = 0);
- static Scene& GetScene(int index = 0);
-
- public:
- //TODO: don't like the name
- void Link(entity* entity);
- bool IsRelevant(entity* entity);
-
- public:
- Camera* GetCamera(int cam_idx = -1);
- int PushCamera(Camera *cam);
- void PopCamera(Camera *cam);
- void SetTileCam(int cam_idx);
-
- void Reset();
-
- std::shared_ptr<Renderer> get_renderer() { return m_renderer; }
-
- /* ============================== */
- # define _KEY_IDX (uintptr_t)key /* TOUKY: I don't like that. hash should be fixed to handle these custom stuff */
- /* ============================== */
- private:
- int HasPrimitiveSource(uintptr_t key);
- int AddPrimitiveSource(uintptr_t key, std::shared_ptr<class PrimitiveSource> source);
- void SetPrimitiveSource(int index, uintptr_t key, std::shared_ptr<class PrimitiveSource> source);
- void ReleasePrimitiveSource(int index, uintptr_t key);
- void ReleaseAllPrimitiveSources(uintptr_t key);
- public:
- /* === Primitive source stuff === */
- /* Returns the number of primitive source set to the given entity */
- template <typename T>
- int HasPrimitiveSource(T* key)
- {
- ASSERT(key);
- return HasPrimitiveSource(_KEY_IDX);
- }
- /* Add a primitive sources linked to the given entity
- * Returns the slot number */
- template <typename T>
- int AddPrimitiveSource(T* key, std::shared_ptr<class PrimitiveSource> source)
- {
- ASSERT(key);
- return AddPrimitiveSource(_KEY_IDX, source);
- }
- /* Update the primitive source at index linked to the given entity
- * Deletes the old one
- * The slot is kept even if source == nullptr */
- template <typename T>
- void SetPrimitiveSource(int index, T* key, std::shared_ptr<class PrimitiveSource> source)
- {
- ASSERT(key);
- SetPrimitiveSource(index, _KEY_IDX, source);
- }
- /* Remove primitive source at index set to the given entity */
- template <typename T>
- void ReleasePrimitiveSource(int index, T* key)
- {
- ASSERT(key);
- ReleasePrimitiveSource(index, _KEY_IDX);
- }
- /* Remove all primitive source set to the given entity */
- template <typename T>
- void ReleaseAllPrimitiveSources(T* key)
- {
- ASSERT(key);
- ReleaseAllPrimitiveSources(_KEY_IDX);
- }
-
- private:
- int HasPrimitiveRenderer(uintptr_t key);
-
- void AddPrimitiveRenderer(uintptr_t key, std::shared_ptr<class PrimitiveRenderer> renderer);
- void SetPrimitiveRenderer(int index, uintptr_t key, std::shared_ptr<class PrimitiveRenderer> renderer);
- void ReleasePrimitiveRenderer(int index, uintptr_t key);
- void ReleaseAllPrimitiveRenderers(uintptr_t key);
- public:
- /* === Primitive renderer stuff === */
- /* Returns the number of primitive renderer set to the given entity */
- template <typename T>
- int HasPrimitiveRenderer(T* key)
- {
- ASSERT(key);
- return HasPrimitiveRenderer(_KEY_IDX);
- }
- /* Add a primitive renderer linked to the given entity
- * The primitive is considered as Fire&Forget and
- * will be destroyed at the end of the frame */
- template <typename T>
- void AddPrimitiveRenderer(T* key, std::shared_ptr<class PrimitiveRenderer> renderer)
- {
- ASSERT(key);
- AddPrimitiveRenderer(_KEY_IDX, renderer);
- }
- /* Update the primitive renderer linked to the given entity
- * Deletes the old one
- * Will assert if renderer == nullptr */
- template <typename T>
- void SetPrimitiveRenderer(int index, T* key, std::shared_ptr<class PrimitiveRenderer> renderer)
- {
- ASSERT(key && renderer);
- SetPrimitiveRenderer(index, _KEY_IDX, renderer);
- }
- /* Remove primitive renderer at index set to the given entity */
- template <typename T>
- void ReleasePrimitiveRenderer(int index, T* key)
- {
- ASSERT(key);
- ReleasePrimitiveRenderer(index, _KEY_IDX);
- }
- /* Remove all primitive renderer set to the given entity */
- template <typename T>
- void ReleaseAllPrimitiveRenderers(T* key)
- {
- ASSERT(key);
- ReleaseAllPrimitiveRenderers(_KEY_IDX);
- }
- /* ============================== */
- # undef _KEY_IDX /* (uintptr_t)key *//* TOUKY: I don't like that. hash should be fixed to handle these custom stuff */
- /* ============================== */
-
- /* FIXME: this should be deprecated -- it doesn't really match
- * the architecture we want to build */
- void AddTile(TileSet *tileset, int id, vec3 pos, vec2 scale, float radians);
- void AddTile(TileSet *tileset, int id, mat4 model);
-
- public:
- void AddLine(vec3 a, vec3 b, vec4 color);
- void AddLine(vec3 a, vec3 b, vec4 color, float duration, int mask);
-
- void AddLight(Light *light);
- array<Light *> const &GetLights();
-
- /* === Render stuff === */
- void SetDisplay(SceneDisplay* display);
- void EnableDisplay();
- void DisableDisplay();
-
- void resize(ivec2 size);
-
- void pre_render(float seconds);
- void render(float seconds);
- void post_render(float seconds);
-
- private:
- void render_primitives();
- void render_tiles();
- void render_lines(float seconds);
-
- ivec2 m_size, m_wanted_size;
-
- std::shared_ptr<Renderer> m_renderer;
-
- //
- // The old SceneData stuff
- //
-
- /* Mask ID */
- /* TODO: Do a mask class that handles more than 64 slots */
- static uint64_t g_used_id;
- uint64_t m_mask_id = 0;
-
- /* Scene display: if none has been set to the scene,
- * the default one created by the app will be used */
- SceneDisplay* m_display = nullptr;
-
- /** Render buffers: where to render to. */
- std::shared_ptr<Framebuffer> m_renderbuffer[4];
-
- struct postprocess
- {
- std::shared_ptr<Shader> m_shader[2];
- std::shared_ptr<VertexBuffer> m_vbo;
- std::shared_ptr<VertexDeclaration> m_vdecl;
- ShaderUniform m_buffer_uni[2][3];
- ShaderAttrib m_coord[2];
- }
- m_pp;
-
- /* Sources are shared by all scenes.
- * Renderers are scene-dependent. They get the primitive in the identical
- * slot to render with the given scene.
- * Primitives and renderers will be kept until:
- * - Updated by entity
- * - Marked Fire&Forget
- * - Scene is destroyed */
- std::map<uintptr_t, array<std::shared_ptr<PrimitiveRenderer>>> m_prim_renderers;
- static std::map<uintptr_t, array<std::shared_ptr<PrimitiveSource>>> g_prim_sources;
- static mutex g_prim_mutex;
-
- Camera *m_default_cam;
- array<Camera *> m_camera_stack;
-
- /* Old line API <P0, P1, COLOR, TIME, MASK> */
- struct line_api
- {
- //float m_duration, m_segment_size;
- //vec4 m_color;
- array<vec3, vec3, vec4, float, int, bool, bool> m_lines;
- int /*m_mask,*/ m_debug_mask;
- std::shared_ptr<Shader> m_shader;
- std::shared_ptr<VertexDeclaration> m_vdecl;
- }
- m_line_api;
-
- /* The old tiles API */
- struct tile_api
- {
- int m_cam;
- array<Tile> m_tiles;
- array<Tile> m_palettes;
- array<Light *> m_lights;
-
- std::shared_ptr<Shader> m_shader;
- std::shared_ptr<Shader> m_palette_shader;
-
- std::shared_ptr<VertexDeclaration> m_vdecl;
- array<std::shared_ptr<VertexBuffer>> m_bufs;
- }
- m_tile_api;
- };
-
- } /* namespace lol */
|