Browse Source

scene: remove useless subobject classes.

legacy
Sam Hocevar 5 years ago
parent
commit
06edad8755
5 changed files with 264 additions and 325 deletions
  1. +3
    -0
      src/application/application.cpp
  2. +0
    -4
      src/application/egl-app.cpp
  3. +0
    -3
      src/application/sdl-app.cpp
  4. +182
    -308
      src/scene.cpp
  5. +79
    -10
      src/scene.h

+ 3
- 0
src/application/application.cpp View File

@@ -161,6 +161,8 @@ static void AppCallback()


Application::Application(char const *name, ivec2 res, float framerate) Application::Application(char const *name, ivec2 res, float framerate)
{ {
ticker::setup(framerate);

auto app_display = new ApplicationDisplay(name, res); auto app_display = new ApplicationDisplay(name, res);
SceneDisplay::Add(app_display); SceneDisplay::Add(app_display);
data = new ApplicationData(name, app_display->resolution(), framerate); data = new ApplicationData(name, app_display->resolution(), framerate);
@@ -194,6 +196,7 @@ void Application::ShowPointer(bool show)


Application::~Application() Application::~Application()
{ {
ticker::teardown();
delete data; delete data;
} }




+ 0
- 4
src/application/egl-app.cpp View File

@@ -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); new SdlInput(res.x, res.y, data->screen_size.x, data->screen_size.y);
# endif # endif


/* Initialise everything */
ticker::setup(fps);
Video::Setup((ivec2)data->screen_size); Video::Setup((ivec2)data->screen_size);
audio::init(); audio::init();
#else #else
@@ -285,8 +283,6 @@ EglApp::~EglApp()
XCloseDisplay(data->dpy); XCloseDisplay(data->dpy);
# endif # endif
#endif #endif
ticker::teardown();

delete data; delete data;
} }




+ 0
- 3
src/application/sdl-app.cpp View File

@@ -176,8 +176,6 @@ SdlApp::SdlApp(char const *title, ivec2 res, float fps) :
ivec2 window_size = res; ivec2 window_size = res;
ivec2 screen_size = res; ivec2 screen_size = res;


/* Initialise everything */
ticker::setup(fps);
audio::init(); audio::init();


/* Autoreleased objects */ /* Autoreleased objects */
@@ -210,7 +208,6 @@ SdlApp::~SdlApp()
SDL_Quit(); SDL_Quit();
#endif #endif
delete data; delete data;
ticker::teardown();
} }


} /* namespace lol */ } /* namespace lol */


+ 182
- 308
src/scene.cpp View File

@@ -40,19 +40,7 @@ namespace lol


array<Scene*> Scene::g_scenes; array<Scene*> 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<SceneDisplay*> m_scene_displays;
static array<SceneDisplay*> g_scene_displays;


static inline void gpu_marker(char const *message) static inline void gpu_marker(char const *message)
{ {
@@ -64,35 +52,34 @@ static inline void gpu_marker(char const *message)
#endif #endif
} }


/*
* Public SceneDisplay class
*/
//
// Public SceneDisplay class
//


void SceneDisplay::Add(SceneDisplay* display) void SceneDisplay::Add(SceneDisplay* display)
{ {
m_scene_displays << display;
g_scene_displays << display;
} }


int SceneDisplay::GetCount() int SceneDisplay::GetCount()
{ {
return m_scene_displays.count();
return g_scene_displays.count();
} }


SceneDisplay* SceneDisplay::GetDisplay(int index) 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); "invalid display index %d", index);
return m_scene_displays[index];
return g_scene_displays[index];
} }


void SceneDisplay::DestroyAll() void SceneDisplay::DestroyAll()
{ {
for (SceneDisplay* display : m_scene_displays)
for (SceneDisplay* display : g_scene_displays)
delete display; delete display;
m_scene_displays.clear();
g_scene_displays.clear();
} }


/* ------------------------------------------------ */
void SceneDisplay::Enable() void SceneDisplay::Enable()
{ {
// TODO: PROFILER STUFF // TODO: PROFILER STUFF
@@ -119,87 +106,9 @@ void PrimitiveRenderer::Render(Scene& scene, std::shared_ptr<PrimitiveSource> pr
* Scene implementation class * 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<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>>> m_prim_sources;
static mutex m_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;
};
uint64_t SceneData::m_used_id = 1;
std::map<uintptr_t, array<std::shared_ptr<PrimitiveSource>>> SceneData::m_prim_sources;
mutex SceneData::m_prim_mutex;
uint64_t Scene::g_used_id = 1;
mutex Scene::g_prim_mutex;
std::map<uintptr_t, array<std::shared_ptr<PrimitiveSource>>> Scene::g_prim_sources;


/* /*
* Public Scene class * Public Scene class
@@ -207,45 +116,49 @@ mutex SceneData::m_prim_mutex;
Scene::Scene(ivec2 size) Scene::Scene(ivec2 size)
: m_size(size), : m_size(size),
m_wanted_size(size), m_wanted_size(size),
data(std::make_unique<SceneData>()),
m_renderer(std::make_shared<Renderer>(size)) m_renderer(std::make_shared<Renderer>(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) for (int i = 0; i < 4; ++i)
data->m_renderbuffer[i] = std::make_shared<Framebuffer>(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<VertexDeclaration>(VertexStream<vec2>(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<Framebuffer>(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<VertexDeclaration>(VertexStream<vec2>(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<vec2> quad { vec2( 1.0, 1.0), vec2(-1.0, -1.0), vec2( 1.0, -1.0), array<vec2> 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), }; vec2(-1.0, -1.0), vec2( 1.0, 1.0), vec2(-1.0, 1.0), };


data->m_pp.m_vbo = std::make_shared<VertexBuffer>(quad.bytes());
void *vertices = data->m_pp.m_vbo->Lock(0, 0);
m_pp.m_vbo = std::make_shared<VertexBuffer>(quad.bytes());
void *vertices = m_pp.m_vbo->Lock(0, 0);
memcpy(vertices, quad.data(), quad.bytes()); 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. */ /* 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); 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<VertexDeclaration>(VertexStream<vec3>(VertexUsage::Position),
VertexStream<vec2>(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<VertexDeclaration>(VertexStream<vec3>(VertexUsage::Position),
VertexStream<vec2>(VertexUsage::TexCoord));


data->m_line_api.m_shader = 0;
data->m_line_api.m_vdecl = std::make_shared<VertexDeclaration>(VertexStream<vec4,vec4>(VertexUsage::Position, VertexUsage::Color));
m_line_api.m_shader = 0;
m_line_api.m_vdecl = std::make_shared<VertexDeclaration>(VertexStream<vec4,vec4>(VertexUsage::Position, VertexUsage::Color));


data->m_line_api.m_debug_mask = 1;
m_line_api.m_debug_mask = 1;
} }


void Scene::resize(ivec2 size) void Scene::resize(ivec2 size)
@@ -253,10 +166,9 @@ void Scene::resize(ivec2 size)
m_wanted_size = size; m_wanted_size = size;
} }


//-----------------------------------------------------------------------------
Scene::~Scene() Scene::~Scene()
{ {
PopCamera(data->m_default_cam);
PopCamera(m_default_cam);


/* FIXME: this must be done while the GL context is still active. /* FIXME: this must be done while the GL context is still active.
* Change the code architecture to make sure of that. */ * Change the code architecture to make sure of that. */
@@ -265,7 +177,6 @@ Scene::~Scene()
Reset(); Reset();
} }


//-----------------------------------------------------------------------------
void Scene::AddNew(ivec2 size) void Scene::AddNew(ivec2 size)
{ {
Scene::g_scenes << new Scene(size); Scene::g_scenes << new Scene(size);
@@ -288,13 +199,11 @@ int Scene::GetCount()
return g_scenes.count(); return g_scenes.count();
} }


//-----------------------------------------------------------------------------
bool Scene::IsReady(int index) bool Scene::IsReady(int index)
{ {
return 0 <= index && index < g_scenes.count() && !!g_scenes[index]; return 0 <= index && index < g_scenes.count() && !!g_scenes[index];
} }


//-----------------------------------------------------------------------------
Scene& Scene::GetScene(int index) Scene& Scene::GetScene(int index)
{ {
ASSERT(0 <= index && index < g_scenes.count() && !!g_scenes[index], ASSERT(0 <= index && index < g_scenes.count() && !!g_scenes[index],
@@ -302,51 +211,40 @@ Scene& Scene::GetScene(int index)
return *g_scenes[index]; return *g_scenes[index];
} }


//-----------------------------------------------------------------------------
void Scene::Link(Entity* entity) 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) 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) 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) int Scene::PushCamera(Camera *cam)
{ {
ASSERT(!!data, "Trying to access a non-ready scene");

Ticker::Ref(cam); 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) 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 /* Parse from the end because that’s probably where we’ll find
* our camera first. */ * 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); Ticker::Unref(cam);
data->m_camera_stack.remove(i);
m_camera_stack.remove(i);
return; return;
} }
} }
@@ -354,52 +252,49 @@ void Scene::PopCamera(Camera *cam)
ASSERT(false, "trying to pop a nonexistent camera from the scene"); ASSERT(false, "trying to pop a nonexistent camera from the scene");
} }


//-----------------------------------------------------------------------------
void Scene::SetTileCam(int cam_idx) 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() void Scene::Reset()
{ {
ASSERT(!!data, "Trying to access a non-ready scene");

/* New scenegraph: Release fire&forget primitives */ /* 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); 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 Scene::HasPrimitiveSource(uintptr_t key)
{ {
int count; 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; return count;
} }


int Scene::AddPrimitiveSource(uintptr_t key, std::shared_ptr<PrimitiveSource> source) int Scene::AddPrimitiveSource(uintptr_t key, std::shared_ptr<PrimitiveSource> source)
{ {
int count; 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; return count;
} }


@@ -411,27 +306,27 @@ void Scene::SetPrimitiveSource(int index, uintptr_t key, std::shared_ptr<Primiti
// Keep reference to old source until AFTER we release the lock // Keep reference to old source until AFTER we release the lock
std::shared_ptr<PrimitiveSource> old; std::shared_ptr<PrimitiveSource> 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 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) void Scene::ReleasePrimitiveSource(int index, uintptr_t key)
{ {
std::shared_ptr<PrimitiveSource> old; std::shared_ptr<PrimitiveSource> 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) void Scene::ReleaseAllPrimitiveSources(uintptr_t key)
@@ -439,26 +334,29 @@ void Scene::ReleaseAllPrimitiveSources(uintptr_t key)
// Delete oldies AFTER having released the lock // Delete oldies AFTER having released the lock
array<std::shared_ptr<PrimitiveSource>> oldies; array<std::shared_ptr<PrimitiveSource>> 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; 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) 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<PrimitiveRenderer> renderer) void Scene::AddPrimitiveRenderer(uintptr_t key, std::shared_ptr<PrimitiveRenderer> renderer)
{ {
renderer->m_fire_and_forget = true; 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<PrimitiveRenderer> renderer) void Scene::SetPrimitiveRenderer(int index, uintptr_t key, std::shared_ptr<PrimitiveRenderer> renderer)
@@ -466,24 +364,23 @@ void Scene::SetPrimitiveRenderer(int index, uintptr_t key, std::shared_ptr<Primi
ASSERT(renderer); ASSERT(renderer);
ASSERT(index >= 0); ASSERT(index >= 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) 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) 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) void Scene::AddTile(TileSet *tileset, int id, vec3 pos, vec2 scale, float radians)
{ {
ASSERT(id < tileset->GetTileCount()); ASSERT(id < tileset->GetTileCount());
@@ -508,62 +405,48 @@ void Scene::AddTile(TileSet *tileset, int id, mat4 model)
t.m_id = id; t.m_id = id;


if (tileset->GetPalette()) if (tileset->GetPalette())
data->m_tile_api.m_palettes.push(t);
m_tile_api.m_palettes.push(t);
else 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) 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) 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) 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<Light *> const &Scene::GetLights() array<Light *> 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) void Scene::SetDisplay(SceneDisplay* display)
{ {
data->m_display = display;
m_display = display;
} }


//-----------------------------------------------------------------------------
void Scene::EnableDisplay() void Scene::EnableDisplay()
{ {
// If no display has been set, use the default one // If no display has been set, use the default one
if (!data->m_display)
if (!m_display)
SetDisplay(SceneDisplay::GetDisplay()); SetDisplay(SceneDisplay::GetDisplay());
data->m_display->Enable();
m_display->Enable();
} }


void Scene::DisableDisplay() void Scene::DisableDisplay()
{ {
ASSERT(data->m_display);
data->m_display->Disable();
ASSERT(m_display);
m_display->Disable();
} }


static bool do_pp = true; static bool do_pp = true;
@@ -577,16 +460,16 @@ void Scene::pre_render(float)
{ {
m_size = m_wanted_size; m_size = m_wanted_size;
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
data->m_renderbuffer[i] = std::make_shared<Framebuffer>(m_size);
m_renderbuffer[i] = std::make_shared<Framebuffer>(m_size);


mat4 proj = mat4::ortho(0.f, (float)m_size.x, 0.f, (float)m_size.y, -1000.f, 1000.f); 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 */ /* First render into the offline buffer */
if (do_pp) if (do_pp)
{ {
data->m_renderbuffer[0]->Bind();
m_renderbuffer[0]->Bind();
} }


{ {
@@ -618,11 +501,11 @@ void Scene::post_render(float)


if (do_pp) if (do_pp)
{ {
data->m_renderbuffer[0]->Unbind();
m_renderbuffer[0]->Unbind();


gpu_marker("PostProcess"); gpu_marker("PostProcess");


data->m_renderbuffer[3]->Bind();
m_renderbuffer[3]->Bind();


render_context rc(m_renderer); render_context rc(m_renderer);
rc.clear_color(vec4(0.f, 0.f, 0.f, 1.f)); 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); m_renderer->Clear(ClearMask::Color | ClearMask::Depth);


/* Execute post process */ /* 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) if (do_pp)
{ {
gpu_marker("Blit frame"); gpu_marker("Blit frame");


data->m_pp.m_shader[0]->Bind();
m_pp.m_shader[0]->Bind();


render_context rc(m_renderer); render_context rc(m_renderer);
rc.clear_color(vec4(0.f, 0.f, 0.f, 1.f)); 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); m_renderer->Clear(ClearMask::Color | ClearMask::Depth);


/* Blit final image to screen */ /* 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) if (do_pp)
{ {
/* Swap back buffers */ /* 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"); gpu_marker("End Render");
} }


//-----------------------------------------------------------------------------
void Scene::render_primitives() void Scene::render_primitives()
{ {
ASSERT(!!data, "Trying to access a non-ready scene");

/* FIXME: Temp fix for mesh having no render context*/ /* FIXME: Temp fix for mesh having no render context*/
render_context rc(m_renderer); render_context rc(m_renderer);
rc.cull_mode(CullMode::Clockwise); rc.cull_mode(CullMode::Clockwise);
rc.depth_func(DepthFunc::LessOrEqual); rc.depth_func(DepthFunc::LessOrEqual);


/* new scenegraph */ /* 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 */ /* TODO: Not sure if thread compliant */
std::shared_ptr<PrimitiveSource> source; std::shared_ptr<PrimitiveSource> 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() void Scene::render_tiles() // XXX: rename to Blit()
{ {
ASSERT(!!data, "Trying to access a non-ready scene");

render_context rc(m_renderer); render_context rc(m_renderer);


/* Early test if nothing needs to be rendered */ /* 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; return;


/* FIXME: we disable culling for now because we don’t have a reliable /* 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); glEnable(GL_TEXTURE_2D);
#endif #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++) 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) if (tiles.count() == 0)
continue; continue;
@@ -741,14 +618,14 @@ void Scene::render_tiles() // XXX: rename to Blit()
shader->Bind(); shader->Bind();


uni_mat = shader->GetUniformLocation("u_projection"); 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"); 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"); uni_mat = shader->GetUniformLocation("u_model");
shader->SetUniform(uni_mat, mat4(1.f)); shader->SetUniform(uni_mat, mat4(1.f));


uni_tex = shader->GetUniformLocation("u_texture"); 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"); uni_texsize = shader->GetUniformLocation("u_texsize");


for (int buf = 0, i = 0, n; i < tiles.count(); i = n, buf += 2) 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<VertexBuffer>(6 * (n - i) * sizeof(vec2)); auto vb2 = std::make_shared<VertexBuffer>(6 * (n - i) * sizeof(vec2));
vec2 *texture = (vec2 *)vb2->Lock(0, 0); 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++) 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()); (vec2)tiles[i].m_tileset->GetTextureSize());


/* Bind vertex and texture coordinate buffers */ /* 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 */ /* 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(); tiles[i].m_tileset->Unbind();
} }


@@ -809,7 +686,7 @@ void Scene::render_tiles() // XXX: rename to Blit()


shader->Unbind(); shader->Unbind();


if (!data->m_tile_api.m_palette_shader)
if (!m_tile_api.m_palette_shader)
break; break;
} }


@@ -818,16 +695,13 @@ void Scene::render_tiles() // XXX: rename to Blit()
#endif #endif
} }


//-----------------------------------------------------------------------------
// FIXME: get rid of the delta time argument // FIXME: get rid of the delta time argument
// XXX: rename to Blit() // XXX: rename to Blit()
void Scene::render_lines(float seconds) void Scene::render_lines(float seconds)
{ {
ASSERT(!!data, "Trying to access a non-ready scene");

render_context rc(m_renderer); render_context rc(m_renderer);


if (!data->m_line_api.m_lines.count())
if (!m_line_api.m_lines.count())
return; return;


rc.depth_func(DepthFunc::LessOrEqual); rc.depth_func(DepthFunc::LessOrEqual);
@@ -835,10 +709,10 @@ void Scene::render_lines(float seconds)
rc.blend_equation(BlendEquation::Add, BlendEquation::Max); rc.blend_equation(BlendEquation::Add, BlendEquation::Max);
rc.alpha_func(AlphaFunc::GreaterOrEqual, 0.01f); 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<vec4, vec4, vec4, vec4> buff; array<vec4, vec4, vec4, vec4> buff;
buff.resize(linecount); buff.resize(linecount);
@@ -846,18 +720,18 @@ void Scene::render_lines(float seconds)
mat4 const inv_view_proj = inverse(GetCamera()->GetProjection() * GetCamera()->GetView()); mat4 const inv_view_proj = inverse(GetCamera()->GetProjection() * GetCamera()->GetView());
for (int i = 0; i < linecount; i++) 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++; 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--; linecount--;
} }
} }
@@ -866,27 +740,27 @@ void Scene::render_lines(float seconds)
memcpy(vertex, buff.data(), buff.bytes()); memcpy(vertex, buff.data(), buff.bytes());
vb->Unlock(); vb->Unlock();


data->m_line_api.m_shader->Bind();
m_line_api.m_shader->Bind();


ShaderUniform uni_mat, uni_tex; ShaderUniform uni_mat, uni_tex;
ShaderAttrib attr_pos, attr_col; 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 */ } /* namespace lol */


+ 79
- 10
src/scene.h View File

@@ -45,6 +45,17 @@ public:
private: private:
}; };


/*
* A quick and dirty Tile structure for 2D blits
*/

struct Tile
{
mat4 m_model;
TileSet *m_tileset;
int m_id;
};

class PrimitiveRenderer class PrimitiveRenderer
{ {
friend class Scene; friend class Scene;
@@ -58,9 +69,6 @@ private:
bool m_fire_and_forget = false; bool m_fire_and_forget = false;
}; };


//-----------------------------------------------------------------------------
class SceneDisplayData;

class SceneDisplay class SceneDisplay
{ {
friend class Scene; friend class Scene;
@@ -88,14 +96,8 @@ public:
//protected: //protected:
virtual void Enable(); virtual void Enable();
virtual void Disable(); virtual void Disable();

private:
SceneDisplayData *data;
}; };


//-----------------------------------------------------------------------------
class SceneData;

class Scene class Scene
{ {
friend class Video; friend class Video;
@@ -264,8 +266,75 @@ private:


ivec2 m_size, m_wanted_size; ivec2 m_size, m_wanted_size;


std::unique_ptr<SceneData> data;
std::shared_ptr<Renderer> m_renderer; 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 */ } /* namespace lol */


Loading…
Cancel
Save