Browse Source

MultiScene: Phase 3: Small PrimitiveSource & PrimitiveRenderer tweaks

undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 9 years ago
parent
commit
49e1588f52
9 changed files with 167 additions and 80 deletions
  1. +1
    -1
      src/base/log.cpp
  2. +2
    -2
      src/lolimgui.cpp
  3. +2
    -2
      src/lolimgui.h
  4. +5
    -2
      src/mesh/mesh.cpp
  5. +3
    -3
      src/mesh/primitive.cpp
  6. +2
    -2
      src/mesh/primitive.h
  7. +65
    -50
      src/scene.cpp
  8. +86
    -17
      src/scene.h
  9. +1
    -1
      src/ticker.cpp

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


+ 2
- 2
src/lolimgui.cpp View File

@@ -259,9 +259,9 @@ void LolImGui::TickDraw(float seconds, Scene &scene)
{ {
super::TickDraw(seconds, scene); super::TickDraw(seconds, scene);


scene.AddPrimitive(new PrimitiveLolImGui());
scene.AddPrimitiveRenderer(this, new PrimitiveLolImGui());
} }
void PrimitiveLolImGui::Render() const
void PrimitiveLolImGui::Render(Scene& scene, PrimitiveSource* primitive)
{ {
g_renderer->Clear(ClearMask::Depth); g_renderer->Clear(ClearMask::Depth);




+ 2
- 2
src/lolimgui.h View File

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


//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class PrimitiveLolImGui : public PrimitiveSource
class PrimitiveLolImGui : public PrimitiveRenderer
{ {
public: public:
PrimitiveLolImGui() { } PrimitiveLolImGui() { }
virtual void Render() const;
virtual void Render(Scene& scene, PrimitiveSource* primitive);
}; };


//bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); //bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks);


+ 5
- 2
src/mesh/mesh.cpp View File

@@ -30,8 +30,11 @@ Mesh::~Mesh()


void Mesh::Render(Scene& scene, mat4 const &matrix) void Mesh::Render(Scene& scene, mat4 const &matrix)
{ {
for (int i = 0; i < m_submeshes.Count(); ++i)
scene.AddPrimitive(new PrimitiveMesh(m_submeshes[i], matrix));
//if (scene.HasPrimitiveRenderer(this) < m_submeshes.Count())
{
for (int i = 0; i < m_submeshes.Count(); ++i)
scene.AddPrimitiveRenderer(this, new PrimitiveMesh(m_submeshes[i], matrix));
}
} }


void Mesh::Render() void Mesh::Render()


+ 3
- 3
src/mesh/primitive.cpp View File

@@ -30,7 +30,7 @@ PrimitiveMesh::~PrimitiveMesh()
{ {
} }


void PrimitiveMesh::Render(Scene& scene)
void PrimitiveMesh::Render(Scene& scene, PrimitiveSource* primitive)
{ {
/* TODO: this should be the main entry for rendering of all /* TODO: this should be the main entry for rendering of all
* primitives found in the scene graph. When we have one. */ * primitives found in the scene graph. When we have one. */
@@ -53,10 +53,10 @@ void PrimitiveMesh::Render(Scene& scene)
/* Per-scene matrices */ /* Per-scene matrices */
ShaderUniform u_mat; ShaderUniform u_mat;
u_mat = shader->GetUniformLocation("u_projection"); u_mat = shader->GetUniformLocation("u_projection");
u_mat = shader->GetUniformLocation("u_view");
u_mat = shader->GetUniformLocation("u_inv_view");
shader->SetUniform(u_mat, scene.GetCamera()->GetProjection()); shader->SetUniform(u_mat, scene.GetCamera()->GetProjection());
u_mat = shader->GetUniformLocation("u_view");
shader->SetUniform(u_mat, scene.GetCamera()->GetView()); shader->SetUniform(u_mat, scene.GetCamera()->GetView());
u_mat = shader->GetUniformLocation("u_inv_view");
shader->SetUniform(u_mat, inverse(scene.GetCamera()->GetView())); shader->SetUniform(u_mat, inverse(scene.GetCamera()->GetView()));


/* Per-object matrices, will be set later */ /* Per-object matrices, will be set later */


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

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


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


public: public:
PrimitiveMesh(SubMesh *submesh, mat4 const &matrix); PrimitiveMesh(SubMesh *submesh, mat4 const &matrix);
virtual ~PrimitiveMesh(); virtual ~PrimitiveMesh();
virtual void Render(Scene& scene);
virtual void Render(Scene& scene, PrimitiveSource* primitive);


private: private:
SubMesh *m_submesh; SubMesh *m_submesh;


+ 65
- 50
src/scene.cpp View File

@@ -46,6 +46,16 @@ struct Tile
int id, o; int id, o;
}; };


/*
* Scene implementation class
*/
void PrimitiveSource::Render(Scene& scene) { UNUSED(scene); }
void PrimitiveRenderer::Render(Scene& scene, PrimitiveSource* primitive)
{
UNUSED(scene);
UNUSED(primitive);
}

/* /*
* Scene implementation class * Scene implementation class
*/ */
@@ -249,6 +259,15 @@ void Scene::Reset()
{ {
ASSERT(!!data, "Trying to access a non-ready scene"); ASSERT(!!data, "Trying to access a non-ready scene");


/* New scenegraph: Release fire&forget primitives */
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)
if (data->m_prim_renderers[key][idx]->m_fire_and_forget)
ReleasePrimitiveRenderer(idx--, key);
}

for (int i = 0; i < data->m_tile_bufs.Count(); i++) for (int i = 0; i < data->m_tile_bufs.Count(); i++)
delete data->m_tile_bufs[i]; delete data->m_tile_bufs[i];
data->m_tile_bufs.Empty(); data->m_tile_bufs.Empty();
@@ -267,71 +286,68 @@ void Scene::AddPrimitive(PrimitiveSource* primitive)
} }


//---- Primitive source stuff ------------------------------------------------- //---- 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)
ptrdiff_t Scene::HasPrimitiveSource(uintptr_t key)
{ {
ASSERT(entity);
ptrdiff_t count; ptrdiff_t count;
SceneData::m_prim_mutex.lock(); SceneData::m_prim_mutex.lock();
{ {
count = SceneData::m_prim_sources[_ENT_IDX].count();
count = SceneData::m_prim_sources[key].count();
} }
SceneData::m_prim_mutex.unlock(); SceneData::m_prim_mutex.unlock();
return count; return count;
} }
ptrdiff_t Scene::AddPrimitiveSource(Entity* entity, PrimitiveSource* source)
ptrdiff_t Scene::AddPrimitiveSource(uintptr_t key, PrimitiveSource* source)
{ {
ASSERT(entity);
ptrdiff_t count; ptrdiff_t count;
SceneData::m_prim_mutex.lock(); SceneData::m_prim_mutex.lock();
{ {
count = SceneData::m_prim_sources[_ENT_IDX].count();
SceneData::m_prim_sources[_ENT_IDX].push(source);
count = SceneData::m_prim_sources[key].count();
SceneData::m_prim_sources[key].push(source);
} }
SceneData::m_prim_mutex.unlock(); SceneData::m_prim_mutex.unlock();
return count; return count;
} }
void Scene::SetPrimitiveSource(ptrdiff_t index, Entity* entity, PrimitiveSource* source)
void Scene::SetPrimitiveSource(ptrdiff_t index, uintptr_t key, PrimitiveSource* source)
{ {
ASSERT(entity);
ASSERT(source);
ASSERT(index < 0);
PrimitiveSource* old = nullptr; PrimitiveSource* old = nullptr;
SceneData::m_prim_mutex.lock(); 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;
if (index < SceneData::m_prim_sources[key].count())
old = SceneData::m_prim_sources[key][index];
else
SceneData::m_prim_sources[key].resize(index + 1);
SceneData::m_prim_sources[key][index] = source;
} }
SceneData::m_prim_mutex.unlock(); SceneData::m_prim_mutex.unlock();


//Delete old AFTER having released the lock //Delete old AFTER having released the lock
if (old) delete old; if (old) delete old;
} }
void Scene::ReleasePrimitiveSource(ptrdiff_t index, Entity* entity)
void Scene::ReleasePrimitiveSource(ptrdiff_t index, uintptr_t key)
{ {
ASSERT(entity);
PrimitiveSource* old = nullptr; PrimitiveSource* old = nullptr;
SceneData::m_prim_mutex.lock(); 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);
ASSERT(0 <= index && index < SceneData::m_prim_sources[key].count());
old = SceneData::m_prim_sources[key][index];
SceneData::m_prim_sources[key].remove(index);
} }
SceneData::m_prim_mutex.unlock(); SceneData::m_prim_mutex.unlock();


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


@@ -341,45 +357,43 @@ void Scene::ReleaseAllPrimitiveSource(Entity* entity)
} }


//---- Primitive renderer stuff ----------------------------------------------- //---- Primitive renderer stuff -----------------------------------------------
ptrdiff_t Scene::HasPrimitiveRenderer(Entity* entity)
ptrdiff_t Scene::HasPrimitiveRenderer(uintptr_t key)
{ {
ASSERT(entity);
return data->m_prim_renderers[_ENT_IDX].count();
return data->m_prim_renderers[key].count();
} }
ptrdiff_t Scene::AddPrimitiveRenderer(Entity* entity, PrimitiveRenderer* renderer)
void Scene::AddPrimitiveRenderer(uintptr_t key, PrimitiveRenderer* renderer)
{ {
ASSERT(entity);
data->m_prim_renderers[_ENT_IDX].push(renderer);
return data->m_prim_renderers[_ENT_IDX].count() - 1;
renderer->m_fire_and_forget = true;
data->m_prim_renderers[key].push(renderer);
} }
void Scene::SetPrimitiveRenderer(ptrdiff_t index, Entity* entity, PrimitiveRenderer* renderer)
void Scene::SetPrimitiveRenderer(ptrdiff_t index, uintptr_t key, 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;
ASSERT(renderer);
ASSERT(index < 0);
if (index < data->m_prim_renderers[key].count())
{
ASSERT(data->m_prim_renderers[key][index]);
delete data->m_prim_renderers[key][index];
}
else
data->m_prim_renderers[key].resize(index + 1);
data->m_prim_renderers[key][index] = renderer;
} }
void Scene::ReleasePrimitiveRenderer(ptrdiff_t index, Entity* entity)
void Scene::ReleasePrimitiveRenderer(ptrdiff_t index, uintptr_t key)
{ {
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);
ASSERT(0 <= index && index < data->m_prim_renderers[key].count());
ASSERT(data->m_prim_renderers[key][index]);
delete data->m_prim_renderers[key][index];
data->m_prim_renderers[key].remove(index);
} }
void Scene::ReleaseAllPrimitiveRenderer(Entity* entity)
void Scene::ReleaseAllPrimitiveRenderer(uintptr_t key)
{ {
ASSERT(entity);
for (PrimitiveRenderer* renderer : data->m_prim_renderers[_ENT_IDX])
for (PrimitiveRenderer* renderer : data->m_prim_renderers[key])
{ {
ASSERT(renderer); ASSERT(renderer);
delete 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) void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float angle)
@@ -478,6 +492,7 @@ void Scene::RenderPrimitives()
{ {
p->Render(*this); p->Render(*this);
} }

/* new scenegraph */ /* new scenegraph */
array<uintptr_t> keys = data->m_prim_renderers.keys(); array<uintptr_t> keys = data->m_prim_renderers.keys();
for (uintptr_t key : keys) for (uintptr_t key : keys)
@@ -485,7 +500,7 @@ void Scene::RenderPrimitives()
for (ptrdiff_t idx = 0; idx < data->m_prim_renderers[key].count(); ++idx) for (ptrdiff_t idx = 0; idx < data->m_prim_renderers[key].count(); ++idx)
{ {
/* TODO: Not sure if thread compliant */ /* 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);
data->m_prim_renderers[key][idx]->Render(*this, idx < SceneData::m_prim_sources[key].count() ? SceneData::m_prim_sources[key][idx] : nullptr);
} }
} }
} }


+ 86
- 17
src/scene.h View File

@@ -37,7 +37,7 @@ class PrimitiveSource
public: public:
PrimitiveSource() { } PrimitiveSource() { }
virtual ~PrimitiveSource() { } virtual ~PrimitiveSource() { }
virtual void Render(Scene& scene) { }
virtual void Render(Scene& scene);


private: private:
}; };
@@ -49,13 +49,12 @@ class PrimitiveRenderer
public: public:
PrimitiveRenderer() { } PrimitiveRenderer() { }
virtual ~PrimitiveRenderer() { } virtual ~PrimitiveRenderer() { }
virtual void Render(PrimitiveSource* primitive) const { UNUSED(primitive); }
virtual void Render(Scene& scene, PrimitiveSource* primitive);


private: private:
bool m_fire_and_forget = false;
}; };


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

//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class Scene class Scene
{ {
@@ -92,38 +91,108 @@ public:
void Reset(); void Reset();


/* New scenegraph */ /* New scenegraph */
void AddPrimitive(PrimitiveSource* primitive);
void AddPrimitive(class PrimitiveSource* primitive);


/* ============================== */
# define _KEY_IDX (uintptr_t)key /* TOUKY: I don't like that. hash should be fixed to handle these custom stuff */
/* ============================== */
private:
ptrdiff_t HasPrimitiveSource(uintptr_t key);
ptrdiff_t AddPrimitiveSource(uintptr_t key, class PrimitiveSource* source);
void SetPrimitiveSource(ptrdiff_t index, uintptr_t key, class PrimitiveSource* source);
void ReleasePrimitiveSource(ptrdiff_t index, uintptr_t key);
void ReleaseAllPrimitiveSource(uintptr_t key);
public:
/* === Primitive source stuff === */ /* === Primitive source stuff === */
/* Returns the number of primitive source set to the given entity */ /* Returns the number of primitive source set to the given entity */
ptrdiff_t HasPrimitiveSource(Entity* entity);
template <typename T>
ptrdiff_t HasPrimitiveSource(T* key)
{
ASSERT(key);
return HasPrimitiveSource(_KEY_IDX);
}
/* Add a primitive sources linked to the given entity /* Add a primitive sources linked to the given entity
* Returns the slot number */ * Returns the slot number */
ptrdiff_t AddPrimitiveSource(Entity* entity, PrimitiveSource* source);
template <typename T>
ptrdiff_t AddPrimitiveSource(T* key, class PrimitiveSource* source)
{
ASSERT(key);
return AddPrimitiveSource(_KEY_IDX, source);
}
/* Update the primitive source at index linked to the given entity /* Update the primitive source at index linked to the given entity
* Deletes the old one * Deletes the old one
* The slot is kept even if source == nullptr */ * The slot is kept even if source == nullptr */
void SetPrimitiveSource(ptrdiff_t index, Entity* entity, PrimitiveSource* source);
template <typename T>
void SetPrimitiveSource(ptrdiff_t index, T* key, class PrimitiveSource* source)
{
ASSERT(key);
SetPrimitiveSource(index, _KEY_IDX, source);
}
/* Remove primitive source at index set to the given entity */ /* Remove primitive source at index set to the given entity */
void ReleasePrimitiveSource(ptrdiff_t index, Entity* entity);
template <typename T>
void ReleasePrimitiveSource(ptrdiff_t index, T* key)
{
ASSERT(key);
ReleasePrimitiveSource(index, _KEY_IDX);
}
/* Remove all primitive source set to the given entity */ /* Remove all primitive source set to the given entity */
void ReleaseAllPrimitiveSource(Entity* entity);
template <typename T>
void ReleaseAllPrimitiveSource(T* key)
{
ASSERT(key);
ReleaseAllPrimitiveSource(_KEY_IDX);
}


private:
ptrdiff_t HasPrimitiveRenderer(uintptr_t key);
void AddPrimitiveRenderer(uintptr_t key, class PrimitiveRenderer* renderer);
void SetPrimitiveRenderer(ptrdiff_t index, uintptr_t key, class PrimitiveRenderer* renderer);
void ReleasePrimitiveRenderer(ptrdiff_t index, uintptr_t key);
void ReleaseAllPrimitiveRenderer(uintptr_t key);
public:
/* === Primitive renderer stuff === */ /* === Primitive renderer stuff === */
/* Returns the number of primitive renderer set to the given entity */ /* Returns the number of primitive renderer set to the given entity */
ptrdiff_t HasPrimitiveRenderer(Entity* entity);
template <typename T>
ptrdiff_t HasPrimitiveRenderer(T* key)
{
ASSERT(key);
return HasPrimitiveRenderer(_KEY_IDX);
}
/* Add a primitive renderer linked to the given entity /* Add a primitive renderer linked to the given entity
* Returns the slot number */
ptrdiff_t AddPrimitiveRenderer(Entity* entity, PrimitiveRenderer* renderer);
* The primitive is considered as Fire&Forget and
* will be destroyed at the end of the frame */
template <typename T>
void AddPrimitiveRenderer(T* key, class PrimitiveRenderer* renderer)
{
ASSERT(key);
AddPrimitiveRenderer(_KEY_IDX, renderer);
}
/* Update the primitive renderer linked to the given entity /* Update the primitive renderer linked to the given entity
* Deletes the old one * Deletes the old one
* Will assert if renderer == nullptr */ * Will assert if renderer == nullptr */
void SetPrimitiveRenderer(ptrdiff_t index, Entity* entity, PrimitiveRenderer* renderer);
template <typename T>
void SetPrimitiveRenderer(ptrdiff_t index, T* key, class PrimitiveRenderer* renderer)
{
ASSERT(key && renderer);
SetPrimitiveRenderer(index, _KEY_IDX, renderer);
}
/* Remove primitive renderer at index set to the given entity */ /* Remove primitive renderer at index set to the given entity */
void ReleasePrimitiveRenderer(ptrdiff_t index, Entity* entity);
template <typename T>
void ReleasePrimitiveRenderer(ptrdiff_t index, T* key)
{
ASSERT(key);
ReleasePrimitiveRenderer(index, _KEY_IDX);
}
/* Remove all primitive renderer set to the given entity */ /* Remove all primitive renderer set to the given entity */
void ReleaseAllPrimitiveRenderer(Entity* entity);

template <typename T>
void ReleaseAllPrimitiveRenderer(T* key)
{
ASSERT(key);
ReleaseAllPrimitiveRenderer(_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 /* FIXME: this should be deprecated -- it doesn't really match
* the architecture we want to build */ * the architecture we want to build */


+ 1
- 1
src/ticker.cpp View File

@@ -464,7 +464,7 @@ void TickerData::DrawThreadTick()
} }


//Do the scene render loop //Do the scene render loop
for (ptrdiff_t idx = 0; idx < Scene::GetCount(); ++idx)
for (ptrdiff_t idx = 0; idx < Scene::GetCount() && !data->quit /* Stop as soon as required */; ++idx)
{ {
Scene& scene = Scene::GetScene(idx); Scene& scene = Scene::GetScene(idx);




Loading…
Cancel
Save