diff --git a/src/application/application.cpp b/src/application/application.cpp index 0d93d355..9d265129 100644 --- a/src/application/application.cpp +++ b/src/application/application.cpp @@ -161,6 +161,8 @@ static void AppCallback() Application::Application(char const *name, ivec2 res, float framerate) { + ticker::setup(framerate); + auto app_display = new ApplicationDisplay(name, res); SceneDisplay::Add(app_display); data = new ApplicationData(name, app_display->resolution(), framerate); @@ -194,6 +196,7 @@ void Application::ShowPointer(bool show) Application::~Application() { + ticker::teardown(); delete data; } diff --git a/src/application/egl-app.cpp b/src/application/egl-app.cpp index 4eb4a8dc..efc6a4a1 100644 --- a/src/application/egl-app.cpp +++ b/src/application/egl-app.cpp @@ -248,8 +248,6 @@ EglApp::EglApp(char const *title, ivec2 res, float fps) : new SdlInput(res.x, res.y, data->screen_size.x, data->screen_size.y); # endif - /* Initialise everything */ - ticker::setup(fps); Video::Setup((ivec2)data->screen_size); audio::init(); #else @@ -285,8 +283,6 @@ EglApp::~EglApp() XCloseDisplay(data->dpy); # endif #endif - ticker::teardown(); - delete data; } diff --git a/src/application/sdl-app.cpp b/src/application/sdl-app.cpp index 01736fda..797cf59a 100644 --- a/src/application/sdl-app.cpp +++ b/src/application/sdl-app.cpp @@ -176,8 +176,6 @@ SdlApp::SdlApp(char const *title, ivec2 res, float fps) : ivec2 window_size = res; ivec2 screen_size = res; - /* Initialise everything */ - ticker::setup(fps); audio::init(); /* Autoreleased objects */ @@ -210,7 +208,6 @@ SdlApp::~SdlApp() SDL_Quit(); #endif delete data; - ticker::teardown(); } } /* namespace lol */ diff --git a/src/scene.cpp b/src/scene.cpp index 80353eae..4347f5f5 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -40,19 +40,7 @@ namespace lol array Scene::g_scenes; -/* - * A quick and dirty Tile structure for 2D blits - */ - -struct Tile -{ - mat4 m_model; - TileSet *m_tileset; - int m_id; -}; - -//----------------------------------------------------------------------------- -static array m_scene_displays; +static array g_scene_displays; static inline void gpu_marker(char const *message) { @@ -64,35 +52,34 @@ static inline void gpu_marker(char const *message) #endif } -/* - * Public SceneDisplay class - */ +// +// Public SceneDisplay class +// void SceneDisplay::Add(SceneDisplay* display) { - m_scene_displays << display; + g_scene_displays << display; } int SceneDisplay::GetCount() { - return m_scene_displays.count(); + return g_scene_displays.count(); } SceneDisplay* SceneDisplay::GetDisplay(int index) { - ASSERT(0 <= index && index < m_scene_displays.count(), + ASSERT(0 <= index && index < g_scene_displays.count(), "invalid display index %d", index); - return m_scene_displays[index]; + return g_scene_displays[index]; } void SceneDisplay::DestroyAll() { - for (SceneDisplay* display : m_scene_displays) + for (SceneDisplay* display : g_scene_displays) delete display; - m_scene_displays.clear(); + g_scene_displays.clear(); } -/* ------------------------------------------------ */ void SceneDisplay::Enable() { // TODO: PROFILER STUFF @@ -119,87 +106,9 @@ void PrimitiveRenderer::Render(Scene& scene, std::shared_ptr pr * Scene implementation class */ -class SceneData -{ - friend class Scene; - -public: - SceneData() - { - /* TODO: FIX THAT */ - ASSERT(!(m_used_id & ((uint64_t)1 << 63)), "Too many scenes !!!!"); - m_mask_id = m_used_id; - m_used_id = m_used_id << 1; - } - -private: - /* Mask ID */ - /* TODO: Do a mask class that handles more than 64 slots */ - static uint64_t m_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 m_renderbuffer[4]; - - struct postprocess - { - std::shared_ptr m_shader[2]; - std::shared_ptr m_vbo; - std::shared_ptr 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>> m_prim_renderers; - static std::map>> m_prim_sources; - static mutex m_prim_mutex; - - Camera *m_default_cam; - array m_camera_stack; - - /* Old line API */ - struct line_api - { - //float m_duration, m_segment_size; - //vec4 m_color; - array m_lines; - int /*m_mask,*/ m_debug_mask; - std::shared_ptr m_shader; - std::shared_ptr m_vdecl; - } - m_line_api; - - /* The old tiles API */ - struct tile_api - { - int m_cam; - array m_tiles; - array m_palettes; - array m_lights; - - std::shared_ptr m_shader; - std::shared_ptr m_palette_shader; - - std::shared_ptr m_vdecl; - array> m_bufs; - } - m_tile_api; -}; -uint64_t SceneData::m_used_id = 1; -std::map>> SceneData::m_prim_sources; -mutex SceneData::m_prim_mutex; +uint64_t Scene::g_used_id = 1; +mutex Scene::g_prim_mutex; +std::map>> Scene::g_prim_sources; /* * Public Scene class @@ -207,45 +116,49 @@ mutex SceneData::m_prim_mutex; Scene::Scene(ivec2 size) : m_size(size), m_wanted_size(size), - data(std::make_unique()), m_renderer(std::make_shared(size)) { + /* TODO: FIX THAT */ + ASSERT(!(g_used_id & ((uint64_t)1 << 63)), "Too many scenes !!!!"); + m_mask_id = g_used_id; + g_used_id = g_used_id << 1; + for (int i = 0; i < 4; ++i) - data->m_renderbuffer[i] = std::make_shared(m_size); - data->m_pp.m_shader[0] = Shader::Create(LOLFX_RESOURCE_NAME(gpu_blit)); - data->m_pp.m_shader[1] = Shader::Create(LOLFX_RESOURCE_NAME(gpu_postprocess)); - data->m_pp.m_coord[0] = data->m_pp.m_shader[0]->GetAttribLocation(VertexUsage::Position, 0); - data->m_pp.m_coord[1] = data->m_pp.m_shader[1]->GetAttribLocation(VertexUsage::Position, 0); - data->m_pp.m_vdecl = std::make_shared(VertexStream(VertexUsage::Position)); - data->m_pp.m_buffer_uni[0][0] = data->m_pp.m_shader[0]->GetUniformLocation("u_buffer"); - data->m_pp.m_buffer_uni[1][0] = data->m_pp.m_shader[1]->GetUniformLocation("u_buffer"); - data->m_pp.m_buffer_uni[1][1] = data->m_pp.m_shader[1]->GetUniformLocation("u_prev_buffer"); - data->m_pp.m_buffer_uni[1][2] = data->m_pp.m_shader[1]->GetUniformLocation("u_prev_final"); + m_renderbuffer[i] = std::make_shared(m_size); + m_pp.m_shader[0] = Shader::Create(LOLFX_RESOURCE_NAME(gpu_blit)); + m_pp.m_shader[1] = Shader::Create(LOLFX_RESOURCE_NAME(gpu_postprocess)); + m_pp.m_coord[0] = m_pp.m_shader[0]->GetAttribLocation(VertexUsage::Position, 0); + m_pp.m_coord[1] = m_pp.m_shader[1]->GetAttribLocation(VertexUsage::Position, 0); + m_pp.m_vdecl = std::make_shared(VertexStream(VertexUsage::Position)); + m_pp.m_buffer_uni[0][0] = m_pp.m_shader[0]->GetUniformLocation("u_buffer"); + m_pp.m_buffer_uni[1][0] = m_pp.m_shader[1]->GetUniformLocation("u_buffer"); + m_pp.m_buffer_uni[1][1] = m_pp.m_shader[1]->GetUniformLocation("u_prev_buffer"); + m_pp.m_buffer_uni[1][2] = m_pp.m_shader[1]->GetUniformLocation("u_prev_final"); array quad { vec2( 1.0, 1.0), vec2(-1.0, -1.0), vec2( 1.0, -1.0), vec2(-1.0, -1.0), vec2( 1.0, 1.0), vec2(-1.0, 1.0), }; - data->m_pp.m_vbo = std::make_shared(quad.bytes()); - void *vertices = data->m_pp.m_vbo->Lock(0, 0); + m_pp.m_vbo = std::make_shared(quad.bytes()); + void *vertices = m_pp.m_vbo->Lock(0, 0); memcpy(vertices, quad.data(), quad.bytes()); - data->m_pp.m_vbo->Unlock(); + m_pp.m_vbo->Unlock(); /* Create a default orthographic camera, in case the user doesn’t. */ - data->m_default_cam = new Camera(); + m_default_cam = new Camera(); mat4 proj = mat4::ortho(0.f, (float)m_size.x, 0.f, (float)m_size.y, -1000.f, 1000.f); - data->m_default_cam->SetProjection(proj); - PushCamera(data->m_default_cam); + m_default_cam->SetProjection(proj); + PushCamera(m_default_cam); - data->m_tile_api.m_cam = -1; - data->m_tile_api.m_shader = 0; - data->m_tile_api.m_palette_shader = 0; - data->m_tile_api.m_vdecl = std::make_shared(VertexStream(VertexUsage::Position), - VertexStream(VertexUsage::TexCoord)); + m_tile_api.m_cam = -1; + m_tile_api.m_shader = 0; + m_tile_api.m_palette_shader = 0; + m_tile_api.m_vdecl = std::make_shared(VertexStream(VertexUsage::Position), + VertexStream(VertexUsage::TexCoord)); - data->m_line_api.m_shader = 0; - data->m_line_api.m_vdecl = std::make_shared(VertexStream(VertexUsage::Position, VertexUsage::Color)); + m_line_api.m_shader = 0; + m_line_api.m_vdecl = std::make_shared(VertexStream(VertexUsage::Position, VertexUsage::Color)); - data->m_line_api.m_debug_mask = 1; + m_line_api.m_debug_mask = 1; } void Scene::resize(ivec2 size) @@ -253,10 +166,9 @@ void Scene::resize(ivec2 size) m_wanted_size = size; } -//----------------------------------------------------------------------------- Scene::~Scene() { - PopCamera(data->m_default_cam); + PopCamera(m_default_cam); /* FIXME: this must be done while the GL context is still active. * Change the code architecture to make sure of that. */ @@ -265,7 +177,6 @@ Scene::~Scene() Reset(); } -//----------------------------------------------------------------------------- void Scene::AddNew(ivec2 size) { Scene::g_scenes << new Scene(size); @@ -288,13 +199,11 @@ int Scene::GetCount() return g_scenes.count(); } -//----------------------------------------------------------------------------- bool Scene::IsReady(int index) { return 0 <= index && index < g_scenes.count() && !!g_scenes[index]; } -//----------------------------------------------------------------------------- Scene& Scene::GetScene(int index) { ASSERT(0 <= index && index < g_scenes.count() && !!g_scenes[index], @@ -302,51 +211,40 @@ Scene& Scene::GetScene(int index) return *g_scenes[index]; } -//----------------------------------------------------------------------------- void Scene::Link(Entity* entity) { - entity->m_scene_mask |= data->m_mask_id; + entity->m_scene_mask |= m_mask_id; } -//----------------------------------------------------------------------------- bool Scene::IsRelevant(Entity* entity) { - return !!(entity->m_scene_mask & data->m_mask_id); + return !!(entity->m_scene_mask & m_mask_id); } -//----------------------------------------------------------------------------- Camera* Scene::GetCamera(int cam_idx) { - ASSERT(!!data, "Trying to access a non-ready scene"); - - return (0 <= cam_idx && cam_idx < data->m_camera_stack.count()) ? - data->m_camera_stack[cam_idx] : - data->m_camera_stack.last(); + return (0 <= cam_idx && cam_idx < m_camera_stack.count()) ? + m_camera_stack[cam_idx] : + m_camera_stack.last(); } -//----------------------------------------------------------------------------- int Scene::PushCamera(Camera *cam) { - ASSERT(!!data, "Trying to access a non-ready scene"); - Ticker::Ref(cam); - data->m_camera_stack.push(cam); - return (int)data->m_camera_stack.count() - 1; + m_camera_stack.push(cam); + return (int)m_camera_stack.count() - 1; } -//----------------------------------------------------------------------------- void Scene::PopCamera(Camera *cam) { - ASSERT(!!data, "Trying to access a non-ready scene"); - /* Parse from the end because that’s probably where we’ll find * our camera first. */ - for (int i = data->m_camera_stack.count(); i--;) + for (int i = m_camera_stack.count(); i--;) { - if (data->m_camera_stack[i] == cam) + if (m_camera_stack[i] == cam) { Ticker::Unref(cam); - data->m_camera_stack.remove(i); + m_camera_stack.remove(i); return; } } @@ -354,52 +252,49 @@ void Scene::PopCamera(Camera *cam) ASSERT(false, "trying to pop a nonexistent camera from the scene"); } -//----------------------------------------------------------------------------- void Scene::SetTileCam(int cam_idx) { - ASSERT(!!data, "Trying to access a non-ready scene"); - - data->m_tile_api.m_cam = cam_idx; + m_tile_api.m_cam = cam_idx; } -//----------------------------------------------------------------------------- void Scene::Reset() { - ASSERT(!!data, "Trying to access a non-ready scene"); - /* New scenegraph: Release fire&forget primitives */ - for (uintptr_t key : keys(data->m_prim_renderers)) + for (uintptr_t key : keys(m_prim_renderers)) { - for (int idx = 0; idx < data->m_prim_renderers[key].count(); ++idx) - if (data->m_prim_renderers[key][idx]->m_fire_and_forget) + for (int idx = 0; idx < m_prim_renderers[key].count(); ++idx) + if (m_prim_renderers[key][idx]->m_fire_and_forget) ReleasePrimitiveRenderer(idx--, key); } - data->m_tile_api.m_bufs.clear(); - data->m_tile_api.m_lights.clear(); + m_tile_api.m_bufs.clear(); + m_tile_api.m_lights.clear(); } -//---- Primitive source stuff ------------------------------------------------- +// +// Primitive source stuff +// + int Scene::HasPrimitiveSource(uintptr_t key) { int count; - SceneData::m_prim_mutex.lock(); + g_prim_mutex.lock(); { - count = SceneData::m_prim_sources[key].count(); + count = g_prim_sources[key].count(); } - SceneData::m_prim_mutex.unlock(); + g_prim_mutex.unlock(); return count; } int Scene::AddPrimitiveSource(uintptr_t key, std::shared_ptr source) { int count; - SceneData::m_prim_mutex.lock(); + g_prim_mutex.lock(); { - count = SceneData::m_prim_sources[key].count(); - SceneData::m_prim_sources[key].push(source); + count = g_prim_sources[key].count(); + g_prim_sources[key].push(source); } - SceneData::m_prim_mutex.unlock(); + g_prim_mutex.unlock(); return count; } @@ -411,27 +306,27 @@ void Scene::SetPrimitiveSource(int index, uintptr_t key, std::shared_ptr old; - SceneData::m_prim_mutex.lock(); + g_prim_mutex.lock(); { - if (index < SceneData::m_prim_sources[key].count()) - old = SceneData::m_prim_sources[key][index]; + if (index < g_prim_sources[key].count()) + old = g_prim_sources[key][index]; else - SceneData::m_prim_sources[key].resize(index + 1); - SceneData::m_prim_sources[key][index] = source; + g_prim_sources[key].resize(index + 1); + g_prim_sources[key][index] = source; } - SceneData::m_prim_mutex.unlock(); + g_prim_mutex.unlock(); } void Scene::ReleasePrimitiveSource(int index, uintptr_t key) { std::shared_ptr old; - SceneData::m_prim_mutex.lock(); + g_prim_mutex.lock(); { - ASSERT(0 <= index && index < SceneData::m_prim_sources[key].count()); - old = SceneData::m_prim_sources[key][index]; - SceneData::m_prim_sources[key].remove(index); + ASSERT(0 <= index && index < g_prim_sources[key].count()); + old = g_prim_sources[key][index]; + g_prim_sources[key].remove(index); } - SceneData::m_prim_mutex.unlock(); + g_prim_mutex.unlock(); } void Scene::ReleaseAllPrimitiveSources(uintptr_t key) @@ -439,26 +334,29 @@ void Scene::ReleaseAllPrimitiveSources(uintptr_t key) // Delete oldies AFTER having released the lock array> oldies; - SceneData::m_prim_mutex.lock(); + g_prim_mutex.lock(); { - oldies.reserve(SceneData::m_prim_sources[key].count()); - for (auto source : SceneData::m_prim_sources[key]) + oldies.reserve(g_prim_sources[key].count()); + for (auto source : g_prim_sources[key]) oldies << source; - SceneData::m_prim_sources[key].clear(); + g_prim_sources[key].clear(); } - SceneData::m_prim_mutex.unlock(); + g_prim_mutex.unlock(); } -//---- Primitive renderer stuff ----------------------------------------------- +// +// Primitive renderer stuff +// + int Scene::HasPrimitiveRenderer(uintptr_t key) { - return data->m_prim_renderers[key].count(); + return m_prim_renderers[key].count(); } void Scene::AddPrimitiveRenderer(uintptr_t key, std::shared_ptr renderer) { renderer->m_fire_and_forget = true; - data->m_prim_renderers[key].push(renderer); + m_prim_renderers[key].push(renderer); } void Scene::SetPrimitiveRenderer(int index, uintptr_t key, std::shared_ptr renderer) @@ -466,24 +364,23 @@ void Scene::SetPrimitiveRenderer(int index, uintptr_t key, std::shared_ptr= 0); - if (index >= data->m_prim_renderers[key].count()) - data->m_prim_renderers[key].resize(index + 1); - data->m_prim_renderers[key][index] = renderer; + if (index >= m_prim_renderers[key].count()) + m_prim_renderers[key].resize(index + 1); + m_prim_renderers[key][index] = renderer; } void Scene::ReleasePrimitiveRenderer(int index, uintptr_t key) { - ASSERT(0 <= index && index < data->m_prim_renderers[key].count()); + ASSERT(0 <= index && index < m_prim_renderers[key].count()); - data->m_prim_renderers[key].remove(index); + m_prim_renderers[key].remove(index); } void Scene::ReleaseAllPrimitiveRenderers(uintptr_t key) { - data->m_prim_renderers[key].clear(); + m_prim_renderers[key].clear(); } -//----------------------------------------------------------------------------- void Scene::AddTile(TileSet *tileset, int id, vec3 pos, vec2 scale, float radians) { ASSERT(id < tileset->GetTileCount()); @@ -508,62 +405,48 @@ void Scene::AddTile(TileSet *tileset, int id, mat4 model) t.m_id = id; if (tileset->GetPalette()) - data->m_tile_api.m_palettes.push(t); + m_tile_api.m_palettes.push(t); else - data->m_tile_api.m_tiles.push(t); + m_tile_api.m_tiles.push(t); } -//----------------------------------------------------------------------------- void Scene::AddLine(vec3 a, vec3 b, vec4 color) { - ASSERT(!!data, "Trying to access a non-ready scene"); - - data->m_line_api.m_lines.push(a, b, color, -1.f, 0xFFFFFFFF, false, false); + m_line_api.m_lines.push(a, b, color, -1.f, 0xFFFFFFFF, false, false); } -//----------------------------------------------------------------------------- void Scene::AddLine(vec3 a, vec3 b, vec4 color, float duration, int mask) { - ASSERT(!!data, "Trying to access a non-ready scene"); - - data->m_line_api.m_lines.push(a, b, color, duration, mask, false, false); + m_line_api.m_lines.push(a, b, color, duration, mask, false, false); } -//----------------------------------------------------------------------------- void Scene::AddLight(Light *l) { - ASSERT(!!data, "Trying to access a non-ready scene"); - - data->m_tile_api.m_lights.push(l); + m_tile_api.m_lights.push(l); } -//----------------------------------------------------------------------------- array const &Scene::GetLights() { - ASSERT(!!data, "Trying to access a non-ready scene"); - - return data->m_tile_api.m_lights; + return m_tile_api.m_lights; } -//----------------------------------------------------------------------------- void Scene::SetDisplay(SceneDisplay* display) { - data->m_display = display; + m_display = display; } -//----------------------------------------------------------------------------- void Scene::EnableDisplay() { // If no display has been set, use the default one - if (!data->m_display) + if (!m_display) SetDisplay(SceneDisplay::GetDisplay()); - data->m_display->Enable(); + m_display->Enable(); } void Scene::DisableDisplay() { - ASSERT(data->m_display); - data->m_display->Disable(); + ASSERT(m_display); + m_display->Disable(); } static bool do_pp = true; @@ -577,16 +460,16 @@ void Scene::pre_render(float) { m_size = m_wanted_size; for (int i = 0; i < 4; ++i) - data->m_renderbuffer[i] = std::make_shared(m_size); + m_renderbuffer[i] = std::make_shared(m_size); mat4 proj = mat4::ortho(0.f, (float)m_size.x, 0.f, (float)m_size.y, -1000.f, 1000.f); - data->m_default_cam->SetProjection(proj); + m_default_cam->SetProjection(proj); } /* First render into the offline buffer */ if (do_pp) { - data->m_renderbuffer[0]->Bind(); + m_renderbuffer[0]->Bind(); } { @@ -618,11 +501,11 @@ void Scene::post_render(float) if (do_pp) { - data->m_renderbuffer[0]->Unbind(); + m_renderbuffer[0]->Unbind(); gpu_marker("PostProcess"); - data->m_renderbuffer[3]->Bind(); + m_renderbuffer[3]->Bind(); render_context rc(m_renderer); rc.clear_color(vec4(0.f, 0.f, 0.f, 1.f)); @@ -630,23 +513,23 @@ void Scene::post_render(float) m_renderer->Clear(ClearMask::Color | ClearMask::Depth); /* Execute post process */ - data->m_pp.m_shader[1]->Bind(); - data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][0], data->m_renderbuffer[0]->GetTextureUniform(), 0); - data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][1], data->m_renderbuffer[1]->GetTextureUniform(), 1); - data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][2], data->m_renderbuffer[2]->GetTextureUniform(), 2); - data->m_pp.m_vdecl->SetStream(data->m_pp.m_vbo, data->m_pp.m_coord[1]); - data->m_pp.m_vdecl->Bind(); - data->m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); - data->m_pp.m_vdecl->Unbind(); - data->m_pp.m_shader[1]->Unbind(); - data->m_renderbuffer[3]->Unbind(); + m_pp.m_shader[1]->Bind(); + m_pp.m_shader[1]->SetUniform(m_pp.m_buffer_uni[1][0], m_renderbuffer[0]->GetTextureUniform(), 0); + m_pp.m_shader[1]->SetUniform(m_pp.m_buffer_uni[1][1], m_renderbuffer[1]->GetTextureUniform(), 1); + m_pp.m_shader[1]->SetUniform(m_pp.m_buffer_uni[1][2], m_renderbuffer[2]->GetTextureUniform(), 2); + m_pp.m_vdecl->SetStream(m_pp.m_vbo, m_pp.m_coord[1]); + m_pp.m_vdecl->Bind(); + m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); + m_pp.m_vdecl->Unbind(); + m_pp.m_shader[1]->Unbind(); + m_renderbuffer[3]->Unbind(); } if (do_pp) { gpu_marker("Blit frame"); - data->m_pp.m_shader[0]->Bind(); + m_pp.m_shader[0]->Bind(); render_context rc(m_renderer); rc.clear_color(vec4(0.f, 0.f, 0.f, 1.f)); @@ -654,57 +537,51 @@ void Scene::post_render(float) m_renderer->Clear(ClearMask::Color | ClearMask::Depth); /* Blit final image to screen */ - data->m_pp.m_shader[0]->SetUniform(data->m_pp.m_buffer_uni[0][0], data->m_renderbuffer[3]->GetTextureUniform(), 3); - data->m_pp.m_vdecl->SetStream(data->m_pp.m_vbo, data->m_pp.m_coord[0]); - data->m_pp.m_vdecl->Bind(); - data->m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); - data->m_pp.m_vdecl->Unbind(); - data->m_pp.m_shader[0]->Unbind(); + m_pp.m_shader[0]->SetUniform(m_pp.m_buffer_uni[0][0], m_renderbuffer[3]->GetTextureUniform(), 3); + m_pp.m_vdecl->SetStream(m_pp.m_vbo, m_pp.m_coord[0]); + m_pp.m_vdecl->Bind(); + m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); + m_pp.m_vdecl->Unbind(); + m_pp.m_shader[0]->Unbind(); } if (do_pp) { /* Swap back buffers */ - std::swap(data->m_renderbuffer[0], data->m_renderbuffer[1]); - std::swap(data->m_renderbuffer[2], data->m_renderbuffer[3]); + std::swap(m_renderbuffer[0], m_renderbuffer[1]); + std::swap(m_renderbuffer[2], m_renderbuffer[3]); } gpu_marker("End Render"); } -//----------------------------------------------------------------------------- void Scene::render_primitives() { - ASSERT(!!data, "Trying to access a non-ready scene"); - /* FIXME: Temp fix for mesh having no render context*/ render_context rc(m_renderer); rc.cull_mode(CullMode::Clockwise); rc.depth_func(DepthFunc::LessOrEqual); /* new scenegraph */ - for (uintptr_t key : keys(data->m_prim_renderers)) + for (uintptr_t key : keys(m_prim_renderers)) { - for (int idx = 0; idx < data->m_prim_renderers[key].count(); ++idx) + for (int idx = 0; idx < m_prim_renderers[key].count(); ++idx) { /* TODO: Not sure if thread compliant */ std::shared_ptr source; - if (idx < SceneData::m_prim_sources[key].count()) - source = SceneData::m_prim_sources[key][idx]; - data->m_prim_renderers[key][idx]->Render(*this, source); + if (idx < g_prim_sources[key].count()) + source = g_prim_sources[key][idx]; + m_prim_renderers[key][idx]->Render(*this, source); } } } -//----------------------------------------------------------------------------- void Scene::render_tiles() // XXX: rename to Blit() { - ASSERT(!!data, "Trying to access a non-ready scene"); - render_context rc(m_renderer); /* Early test if nothing needs to be rendered */ - if (!data->m_tile_api.m_tiles.count() && !data->m_tile_api.m_palettes.count()) + if (!m_tile_api.m_tiles.count() && !m_tile_api.m_palettes.count()) return; /* FIXME: we disable culling for now because we don’t have a reliable @@ -720,15 +597,15 @@ void Scene::render_tiles() // XXX: rename to Blit() glEnable(GL_TEXTURE_2D); #endif - if (!data->m_tile_api.m_shader) - data->m_tile_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_tile)); - if (!data->m_tile_api.m_palette_shader && data->m_tile_api.m_palettes.count()) - data->m_tile_api.m_palette_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_palette)); + if (!m_tile_api.m_shader) + m_tile_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_tile)); + if (!m_tile_api.m_palette_shader && m_tile_api.m_palettes.count()) + m_tile_api.m_palette_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_palette)); for (int p = 0; p < 2; p++) { - auto shader = (p == 0) ? data->m_tile_api.m_shader : data->m_tile_api.m_palette_shader; - auto &tiles = (p == 0) ? data->m_tile_api.m_tiles : data->m_tile_api.m_palettes; + auto shader = (p == 0) ? m_tile_api.m_shader : m_tile_api.m_palette_shader; + auto &tiles = (p == 0) ? m_tile_api.m_tiles : m_tile_api.m_palettes; if (tiles.count() == 0) continue; @@ -741,14 +618,14 @@ void Scene::render_tiles() // XXX: rename to Blit() shader->Bind(); uni_mat = shader->GetUniformLocation("u_projection"); - shader->SetUniform(uni_mat, GetCamera(data->m_tile_api.m_cam)->GetProjection()); + shader->SetUniform(uni_mat, GetCamera(m_tile_api.m_cam)->GetProjection()); uni_mat = shader->GetUniformLocation("u_view"); - shader->SetUniform(uni_mat, GetCamera(data->m_tile_api.m_cam)->GetView()); + shader->SetUniform(uni_mat, GetCamera(m_tile_api.m_cam)->GetView()); uni_mat = shader->GetUniformLocation("u_model"); shader->SetUniform(uni_mat, mat4(1.f)); uni_tex = shader->GetUniformLocation("u_texture"); - uni_pal = data->m_tile_api.m_palette_shader ? data->m_tile_api.m_palette_shader->GetUniformLocation("u_palette") : ShaderUniform(); + uni_pal = m_tile_api.m_palette_shader ? m_tile_api.m_palette_shader->GetUniformLocation("u_palette") : ShaderUniform(); uni_texsize = shader->GetUniformLocation("u_texsize"); for (int buf = 0, i = 0, n; i < tiles.count(); i = n, buf += 2) @@ -764,8 +641,8 @@ void Scene::render_tiles() // XXX: rename to Blit() auto vb2 = std::make_shared(6 * (n - i) * sizeof(vec2)); vec2 *texture = (vec2 *)vb2->Lock(0, 0); - data->m_tile_api.m_bufs.push(vb1); - data->m_tile_api.m_bufs.push(vb2); + m_tile_api.m_bufs.push(vb1); + m_tile_api.m_bufs.push(vb2); for (int j = i; j < n; j++) { @@ -795,13 +672,13 @@ void Scene::render_tiles() // XXX: rename to Blit() (vec2)tiles[i].m_tileset->GetTextureSize()); /* Bind vertex and texture coordinate buffers */ - data->m_tile_api.m_vdecl->Bind(); - data->m_tile_api.m_vdecl->SetStream(vb1, attr_pos); - data->m_tile_api.m_vdecl->SetStream(vb2, attr_tex); + m_tile_api.m_vdecl->Bind(); + m_tile_api.m_vdecl->SetStream(vb1, attr_pos); + m_tile_api.m_vdecl->SetStream(vb2, attr_tex); /* Draw arrays */ - data->m_tile_api.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); - data->m_tile_api.m_vdecl->Unbind(); + m_tile_api.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); + m_tile_api.m_vdecl->Unbind(); tiles[i].m_tileset->Unbind(); } @@ -809,7 +686,7 @@ void Scene::render_tiles() // XXX: rename to Blit() shader->Unbind(); - if (!data->m_tile_api.m_palette_shader) + if (!m_tile_api.m_palette_shader) break; } @@ -818,16 +695,13 @@ void Scene::render_tiles() // XXX: rename to Blit() #endif } -//----------------------------------------------------------------------------- // FIXME: get rid of the delta time argument // XXX: rename to Blit() void Scene::render_lines(float seconds) { - ASSERT(!!data, "Trying to access a non-ready scene"); - render_context rc(m_renderer); - if (!data->m_line_api.m_lines.count()) + if (!m_line_api.m_lines.count()) return; rc.depth_func(DepthFunc::LessOrEqual); @@ -835,10 +709,10 @@ void Scene::render_lines(float seconds) rc.blend_equation(BlendEquation::Add, BlendEquation::Max); rc.alpha_func(AlphaFunc::GreaterOrEqual, 0.01f); - int linecount = (int)data->m_line_api.m_lines.count(); + int linecount = (int)m_line_api.m_lines.count(); - if (!data->m_line_api.m_shader) - data->m_line_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_line)); + if (!m_line_api.m_shader) + m_line_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_line)); array buff; buff.resize(linecount); @@ -846,18 +720,18 @@ void Scene::render_lines(float seconds) mat4 const inv_view_proj = inverse(GetCamera()->GetProjection() * GetCamera()->GetView()); for (int i = 0; i < linecount; i++) { - if (data->m_line_api.m_lines[i].m5 & data->m_line_api.m_debug_mask) + if (m_line_api.m_lines[i].m5 & m_line_api.m_debug_mask) { - buff[real_linecount].m1 = vec4(data->m_line_api.m_lines[i].m1, (float)data->m_line_api.m_lines[i].m6); - buff[real_linecount].m2 = data->m_line_api.m_lines[i].m3; - buff[real_linecount].m3 = vec4(data->m_line_api.m_lines[i].m2, (float)data->m_line_api.m_lines[i].m7); - buff[real_linecount].m4 = data->m_line_api.m_lines[i].m3; + buff[real_linecount].m1 = vec4(m_line_api.m_lines[i].m1, (float)m_line_api.m_lines[i].m6); + buff[real_linecount].m2 = m_line_api.m_lines[i].m3; + buff[real_linecount].m3 = vec4(m_line_api.m_lines[i].m2, (float)m_line_api.m_lines[i].m7); + buff[real_linecount].m4 = m_line_api.m_lines[i].m3; real_linecount++; } - data->m_line_api.m_lines[i].m4 -= seconds; - if (data->m_line_api.m_lines[i].m4 < 0.f) + m_line_api.m_lines[i].m4 -= seconds; + if (m_line_api.m_lines[i].m4 < 0.f) { - data->m_line_api.m_lines.remove_swap(i--); + m_line_api.m_lines.remove_swap(i--); linecount--; } } @@ -866,27 +740,27 @@ void Scene::render_lines(float seconds) memcpy(vertex, buff.data(), buff.bytes()); vb->Unlock(); - data->m_line_api.m_shader->Bind(); + m_line_api.m_shader->Bind(); ShaderUniform uni_mat, uni_tex; ShaderAttrib attr_pos, attr_col; - attr_pos = data->m_line_api.m_shader->GetAttribLocation(VertexUsage::Position, 0); - attr_col = data->m_line_api.m_shader->GetAttribLocation(VertexUsage::Color, 0); + attr_pos = m_line_api.m_shader->GetAttribLocation(VertexUsage::Position, 0); + attr_col = m_line_api.m_shader->GetAttribLocation(VertexUsage::Color, 0); - data->m_line_api.m_shader->Bind(); + m_line_api.m_shader->Bind(); - uni_mat = data->m_line_api.m_shader->GetUniformLocation("u_projection"); - data->m_line_api.m_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); - uni_mat = data->m_line_api.m_shader->GetUniformLocation("u_view"); - data->m_line_api.m_shader->SetUniform(uni_mat, GetCamera()->GetView()); + uni_mat = m_line_api.m_shader->GetUniformLocation("u_projection"); + m_line_api.m_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); + uni_mat = m_line_api.m_shader->GetUniformLocation("u_view"); + m_line_api.m_shader->SetUniform(uni_mat, GetCamera()->GetView()); - data->m_line_api.m_vdecl->Bind(); - data->m_line_api.m_vdecl->SetStream(vb, attr_pos, attr_col); - data->m_line_api.m_vdecl->DrawElements(MeshPrimitive::Lines, 0, 2 * real_linecount); - data->m_line_api.m_vdecl->Unbind(); - data->m_line_api.m_shader->Unbind(); + m_line_api.m_vdecl->Bind(); + m_line_api.m_vdecl->SetStream(vb, attr_pos, attr_col); + m_line_api.m_vdecl->DrawElements(MeshPrimitive::Lines, 0, 2 * real_linecount); + m_line_api.m_vdecl->Unbind(); + m_line_api.m_shader->Unbind(); - //data->m_line_api.m_lines.clear(); + //m_line_api.m_lines.clear(); } } /* namespace lol */ diff --git a/src/scene.h b/src/scene.h index 87a0dd1a..1942a066 100644 --- a/src/scene.h +++ b/src/scene.h @@ -45,6 +45,17 @@ public: 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; @@ -58,9 +69,6 @@ private: bool m_fire_and_forget = false; }; -//----------------------------------------------------------------------------- -class SceneDisplayData; - class SceneDisplay { friend class Scene; @@ -88,14 +96,8 @@ public: //protected: virtual void Enable(); virtual void Disable(); - -private: - SceneDisplayData *data; }; -//----------------------------------------------------------------------------- -class SceneData; - class Scene { friend class Video; @@ -264,8 +266,75 @@ private: ivec2 m_size, m_wanted_size; - std::unique_ptr data; std::shared_ptr 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 m_renderbuffer[4]; + + struct postprocess + { + std::shared_ptr m_shader[2]; + std::shared_ptr m_vbo; + std::shared_ptr 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>> m_prim_renderers; + static std::map>> g_prim_sources; + static mutex g_prim_mutex; + + Camera *m_default_cam; + array m_camera_stack; + + /* Old line API */ + struct line_api + { + //float m_duration, m_segment_size; + //vec4 m_color; + array m_lines; + int /*m_mask,*/ m_debug_mask; + std::shared_ptr m_shader; + std::shared_ptr m_vdecl; + } + m_line_api; + + /* The old tiles API */ + struct tile_api + { + int m_cam; + array m_tiles; + array m_palettes; + array m_lights; + + std::shared_ptr m_shader; + std::shared_ptr m_palette_shader; + + std::shared_ptr m_vdecl; + array> m_bufs; + } + m_tile_api; }; } /* namespace lol */