Browse Source

MultiScene: Phase 3: Added PrimitiveSource & PrimitiveRenderer and corresponding rendering pipeline

undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 9 years ago
parent
commit
51a4b892c7
5 changed files with 176 additions and 23 deletions
  1. +1
    -1
      src/base/log.cpp
  2. +1
    -1
      src/lolimgui.h
  3. +1
    -1
      src/mesh/primitive.h
  4. +133
    -9
      src/scene.cpp
  5. +40
    -11
      src/scene.h

+ 1
- 1
src/base/log.cpp View File

@@ -95,7 +95,7 @@ void Log::Helper(MessageType type, char const *fmt, va_list ap)

array<WCHAR> widechar;
widechar.Resize(buf.Count() + 1);
MultiByteToWideChar(CP_UTF8, 0, buf.C(), buf.Count() + 1, widechar.Data(), widechar.Count());
MultiByteToWideChar(CP_UTF8, 0, buf.C(), (int)buf.Count() + 1, widechar.Data(), widechar.Count());
OutputDebugStringW(widechar.Data());
# else
fprintf(stderr, "%s: ", prefix[type]);


+ 1
- 1
src/lolimgui.h View File

@@ -174,7 +174,7 @@ protected:
};

//-----------------------------------------------------------------------------
class PrimitiveLolImGui : public Primitive
class PrimitiveLolImGui : public PrimitiveSource
{
public:
PrimitiveLolImGui() { }


+ 1
- 1
src/mesh/primitive.h View File

@@ -18,7 +18,7 @@
namespace lol
{

class PrimitiveMesh : public Primitive
class PrimitiveMesh : public PrimitiveSource
{
friend class Scene;



+ 133
- 9
src/scene.cpp View File

@@ -69,11 +69,15 @@ private:
uint64_t m_mask_id = 0;

/* New scenegraph */
array<Primitive*> m_primitives;
/* Primitives will be kept until:
array<PrimitiveSource*> m_primitives;
/* Primitives 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
* - Scene is destroyed */
map<uintptr_t, array<Primitive*, PrimitiveSettings*> > m_primitives_;
map<uintptr_t, array<PrimitiveRenderer*> > m_prim_renderers;
static map<uintptr_t, array<PrimitiveSource*> > m_prim_sources;
static mutex m_prim_mutex;

/* Old API <P0, P1, COLOR, TIME, MASK> */
float m_new_line_time;
@@ -99,6 +103,8 @@ private:
array<Camera *> m_camera_stack;
};
uint64_t SceneData::m_used_id = 1;
map<uintptr_t, array<PrimitiveSource*> > SceneData::m_prim_sources;
mutex SceneData::m_prim_mutex;

/*
* Public Scene class
@@ -255,17 +261,125 @@ void Scene::Reset()
}

//-----------------------------------------------------------------------------
void Scene::AddPrimitive(Primitive* primitive)
void Scene::AddPrimitive(PrimitiveSource* primitive)
{
data->m_primitives.Push(primitive);
}

//-----------------------------------------------------------------------------
void Scene::AddPrimitive(Entity* entity, Primitive* primitive)
//---- Primitive source stuff -------------------------------------------------
#define _ENT_IDX (uintptr_t)entity /* TOUKY: I don't like that. hash should be fixed to handle these custom stuff */
//---- Primitive source stuff -------------------------------------------------
ptrdiff_t Scene::HasPrimitiveSource(Entity* entity)
{
ASSERT(entity);
ptrdiff_t count;
SceneData::m_prim_mutex.lock();
{
count = SceneData::m_prim_sources[_ENT_IDX].count();
}
SceneData::m_prim_mutex.unlock();
return count;
}
ptrdiff_t Scene::AddPrimitiveSource(Entity* entity, PrimitiveSource* source)
{
ASSERT(entity);
ptrdiff_t count;
SceneData::m_prim_mutex.lock();
{
count = SceneData::m_prim_sources[_ENT_IDX].count();
SceneData::m_prim_sources[_ENT_IDX].push(source);
}
SceneData::m_prim_mutex.unlock();
return count;
}
void Scene::SetPrimitiveSource(ptrdiff_t index, Entity* entity, PrimitiveSource* source)
{
ASSERT(entity);
PrimitiveSource* old = nullptr;
SceneData::m_prim_mutex.lock();
{
ASSERT(0 <= index && index < SceneData::m_prim_sources[_ENT_IDX].count());
old = SceneData::m_prim_sources[_ENT_IDX][index];
SceneData::m_prim_sources[_ENT_IDX][index] = source;
}
SceneData::m_prim_mutex.unlock();

//Delete old AFTER having released the lock
if (old) delete old;
}
void Scene::ReleasePrimitiveSource(ptrdiff_t index, Entity* entity)
{
/* FIXME: data->m_primitives_ is never emptied or even used. */
data->m_primitives_[(uintptr_t)entity /* I don't like that */].push(primitive, nullptr);
ASSERT(entity);
PrimitiveSource* old = nullptr;
SceneData::m_prim_mutex.lock();
{
ASSERT(0 <= index && index < SceneData::m_prim_sources[_ENT_IDX].count());
old = SceneData::m_prim_sources[_ENT_IDX][index];
SceneData::m_prim_sources[_ENT_IDX].remove(index);
}
SceneData::m_prim_mutex.unlock();

//Delete old AFTER having released the lock
if (old) delete old;
}
void Scene::ReleaseAllPrimitiveSource(Entity* entity)
{
ASSERT(entity);
array<PrimitiveSource*> oldies;
SceneData::m_prim_mutex.lock();
{
oldies.reserve(SceneData::m_prim_sources[_ENT_IDX].count());
for (PrimitiveSource* source : SceneData::m_prim_sources[_ENT_IDX])
oldies << source;
SceneData::m_prim_sources[_ENT_IDX].empty();
}
SceneData::m_prim_mutex.unlock();

//Delete oldies AFTER having released the lock
for (PrimitiveSource* old : oldies)
if (old) delete old;
}

//---- Primitive renderer stuff -----------------------------------------------
ptrdiff_t Scene::HasPrimitiveRenderer(Entity* entity)
{
ASSERT(entity);
return data->m_prim_renderers[_ENT_IDX].count();
}
ptrdiff_t Scene::AddPrimitiveRenderer(Entity* entity, PrimitiveRenderer* renderer)
{
ASSERT(entity);
data->m_prim_renderers[_ENT_IDX].push(renderer);
return data->m_prim_renderers[_ENT_IDX].count() - 1;
}
void Scene::SetPrimitiveRenderer(ptrdiff_t index, Entity* entity, PrimitiveRenderer* renderer)
{
ASSERT(entity && renderer);
ASSERT(0 <= index && index < data->m_prim_renderers[_ENT_IDX].count());
ASSERT(data->m_prim_renderers[_ENT_IDX][index]);
delete data->m_prim_renderers[_ENT_IDX][index];
data->m_prim_renderers[_ENT_IDX][index] = renderer;
}
void Scene::ReleasePrimitiveRenderer(ptrdiff_t index, Entity* entity)
{
ASSERT(entity);
ASSERT(0 <= index && index < data->m_prim_renderers[_ENT_IDX].count());
ASSERT(data->m_prim_renderers[_ENT_IDX][index]);
delete data->m_prim_renderers[_ENT_IDX][index];
data->m_prim_renderers[_ENT_IDX].remove(index);
}
void Scene::ReleaseAllPrimitiveRenderer(Entity* entity)
{
ASSERT(entity);
for (PrimitiveRenderer* renderer : data->m_prim_renderers[_ENT_IDX])
{
ASSERT(renderer);
delete renderer;
}
}
//---- Primitive source stuff -------------------------------------------------
#undef _ENT_IDX //(uintptr_t)entity /* TOUKY: I don't like that. hash should be fixed to handle these custom stuff */
//---- Primitive source stuff -------------------------------------------------

//-----------------------------------------------------------------------------
void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float angle)
@@ -360,10 +474,20 @@ void Scene::RenderPrimitives()

/* TODO: this should be the main entry for rendering of all
* primitives found in the scene graph. When we have one. */
for (Primitive* p : data->m_primitives)
for (PrimitiveSource* p : data->m_primitives)
{
p->Render(*this);
}
/* new scenegraph */
array<uintptr_t> keys = data->m_prim_renderers.keys();
for (uintptr_t key : keys)
{
for (ptrdiff_t idx = 0; idx < data->m_prim_renderers[key].count(); ++idx)
{
/* TODO: Not sure if thread compliant */
data->m_prim_renderers[key][idx]->Render(idx < SceneData::m_prim_sources[key].count() ? SceneData::m_prim_sources[key][idx] : nullptr);
}
}
}

//-----------------------------------------------------------------------------


+ 40
- 11
src/scene.h View File

@@ -30,26 +30,26 @@ namespace lol
class SceneData;

//-----------------------------------------------------------------------------
class Primitive
class PrimitiveSource
{
friend class Scene;

public:
Primitive() { }
virtual ~Primitive() { }
PrimitiveSource() { }
virtual ~PrimitiveSource() { }
virtual void Render(Scene& scene) { }

private:
};

class PrimitiveSettings
class PrimitiveRenderer
{
friend class Scene;

public:
PrimitiveSettings() { }
virtual ~PrimitiveSettings() { }
virtual void ApplyTo(Primitive* primitive) const { UNUSED(primitive); }
PrimitiveRenderer() { }
virtual ~PrimitiveRenderer() { }
virtual void Render(PrimitiveSource* primitive) const { UNUSED(primitive); }

private:
};
@@ -69,8 +69,7 @@ private:

public:
static void AddNew(ivec2 size);
private:
//Private because I don't know if we should have it
private: //Private because I don't know if we should have it
static void DestroyScene(Scene* scene);
private:
static void DestroyAll();
@@ -93,8 +92,38 @@ public:
void Reset();

/* New scenegraph */
void AddPrimitive(Primitive* primitive);
void AddPrimitive(Entity* entity, Primitive* primitive);
void AddPrimitive(PrimitiveSource* primitive);

/* === Primitive source stuff === */
/* Returns the number of primitive source set to the given entity */
ptrdiff_t HasPrimitiveSource(Entity* entity);
/* Add a primitive sources linked to the given entity
* Returns the slot number */
ptrdiff_t AddPrimitiveSource(Entity* entity, PrimitiveSource* source);
/* Update the primitive source at index linked to the given entity
* Deletes the old one
* The slot is kept even if source == nullptr */
void SetPrimitiveSource(ptrdiff_t index, Entity* entity, PrimitiveSource* source);
/* Remove primitive source at index set to the given entity */
void ReleasePrimitiveSource(ptrdiff_t index, Entity* entity);
/* Remove all primitive source set to the given entity */
void ReleaseAllPrimitiveSource(Entity* entity);

/* === Primitive renderer stuff === */
/* Returns the number of primitive renderer set to the given entity */
ptrdiff_t HasPrimitiveRenderer(Entity* entity);
/* Add a primitive renderer linked to the given entity
* Returns the slot number */
ptrdiff_t AddPrimitiveRenderer(Entity* entity, PrimitiveRenderer* renderer);
/* Update the primitive renderer linked to the given entity
* Deletes the old one
* Will assert if renderer == nullptr */
void SetPrimitiveRenderer(ptrdiff_t index, Entity* entity, PrimitiveRenderer* renderer);
/* Remove primitive renderer at index set to the given entity */
void ReleasePrimitiveRenderer(ptrdiff_t index, Entity* entity);
/* Remove all primitive renderer set to the given entity */
void ReleaseAllPrimitiveRenderer(Entity* entity);


/* FIXME: this should be deprecated -- it doesn't really match
* the architecture we want to build */


Loading…
Cancel
Save