Skip to content

Commit

Permalink
refactor: added a basic scene graph
Browse files Browse the repository at this point in the history
  • Loading branch information
tomezpl committed Jan 4, 2024
1 parent 71ff1ad commit 05d2553
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 22 deletions.
5 changes: 5 additions & 0 deletions src/examples/demo/DemoApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ class DemoApp : public system::BaseApp
engine.Setup();
m_Camera.Transform().Origin(m_Camera.Transform().Forward() * -2.f);

auto cubeMesh = lepus::gfx::GLMesh(lepus::utility::Primitives::Cube());
auto cube = lepus::gfx::Renderable<lepus::gfx::GLMesh>(&cubeMesh, lepus::math::Transform());
auto cube2 = lepus::gfx::Renderable<lepus::gfx::GLMesh>(&cubeMesh, lepus::math::Transform());
api.GetSceneGraph().AddChild(&cube);
api.GetSceneGraph().AddChild(&cube2);

m_UniformState.projMatrix = m_Camera.BuildPerspectiveMatrix();
((lepus::gfx::GLMatrixUniformBinding*)api.GetUniform<lepus::gfx::GLMatrixUniformBinding>(LEPUS_GFX_UNIFORMS_GLOBAL_PROJECTION_MATRIX))->Value((float*)m_UniformState.projMatrix.data());
Expand Down
16 changes: 9 additions & 7 deletions src/lepus/gfx/GraphicsEngine/Apis/ApiGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "ApiGL/Bindings.h"
#include "ApiGL/Types/GLMesh.h"
#include <lepus/gfx/SceneGraph.h>

namespace lepus
{
Expand Down Expand Up @@ -59,6 +60,8 @@ namespace lepus
}
};

typedef lepus::gfx::SceneGraph<GLMesh, lepus::gfx::Renderable<GLMesh>> GLSceneGraph;

template GraphicsApiGLOptions& GraphicsApi::GetOptions<GraphicsApiGLOptions>();

class GraphicsApiGL : public GraphicsApi
Expand All @@ -71,12 +74,6 @@ namespace lepus
/// @brief Handle to the vertex array objects.
GLuint vao;

/// @brief Handle to the global VBO.
GLuint vbo[_meshCount] = { 0, 0 };

/// @brief Handle to the global IBO.
GLuint ibo[_meshCount] = { 0, 0 };

/// @brief List with all uniforms used by the API.
// TODO: Change to array - might get better cache/locality to improve access times.
std::forward_list<lepus::gfx::GLUniformBinding<void*>*> uniforms;
Expand All @@ -88,7 +85,7 @@ namespace lepus

GLuint m_Programs[GraphicsApiGLOptions::ProgramCount];

GLMesh m_Meshes[_meshCount];
GLSceneGraph m_Scene;

private:
void SetupVertexArrays();
Expand Down Expand Up @@ -126,6 +123,11 @@ namespace lepus

void UpdateUniforms() override;

inline GLSceneGraph& GetSceneGraph()
{
return m_Scene;
}

void Draw() override;

void ClearFrameBuffer(float r, float g, float b) override;
Expand Down
58 changes: 43 additions & 15 deletions src/lepus/gfx/GraphicsEngine/Apis/ApiGL/ApiGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ using namespace lepus::gfx;
void GraphicsApiGL::Init(GraphicsApiOptions* options)
{
InitInternal<GraphicsApiGLOptions>((GraphicsApiGLOptions*)options);

m_Scene = GLSceneGraph();
}

void GraphicsApiGL::SetupVertexArrays()
Expand All @@ -14,20 +16,10 @@ void GraphicsApiGL::SetupVertexArrays()
glBindVertexArray(m_Pipeline.vao);
}

// TODO: rename this, or move to SetupVertexArrays?
void GraphicsApiGL::SetupBuffers()
{
glBindVertexArray(m_Pipeline.vao);

// Creating a mesh from built-in primitive geometry.
m_Meshes[0] = GLMesh(lepus::utility::Primitives::Cube());
m_Pipeline.vbo[0] = m_Meshes[0].GetVBO();
m_Pipeline.ibo[0] = m_Meshes[0].GetIBO();

// Creating a mesh by copying the first mesh.
// Vertex & index data is shared with the first mesh, but uploaded to a separate pair of OpenGL buffers.
m_Meshes[1] = GLMesh(m_Meshes[0]);
m_Pipeline.vbo[1] = m_Meshes[1].GetVBO();
m_Pipeline.ibo[1] = m_Meshes[1].GetIBO();
}

void GraphicsApiGL::SetupShaders()
Expand Down Expand Up @@ -104,13 +96,49 @@ void GraphicsApiGL::Draw()
glUseProgram(m_Programs[0]);

glBindVertexArray(m_Pipeline.vao);
for (uint8_t meshIndex = 0; meshIndex < _meshCount; meshIndex++)

const GLSceneGraph::Node* currentNode = m_Scene.Root();

bool branchComplete = false;

while (currentNode)
{
glBindBuffer(GL_ARRAY_BUFFER, m_Pipeline.vbo[meshIndex]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Pipeline.ibo[meshIndex]);
if (!branchComplete && !currentNode->IsRoot())
{
typedef lepus::gfx::Renderable<GLMesh> GLRenderable;
const GLRenderable* renderable = currentNode->GetRenderable();
if (renderable)
{
glBindBuffer(GL_ARRAY_BUFFER, renderable->GetMesh()->GetVBO());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderable->GetMesh()->GetIBO());

glDrawElements(GL_TRIANGLES, (GLsizei)m_Meshes[meshIndex].IndexCount(), GL_UNSIGNED_INT, 0);
glDrawElements(GL_TRIANGLES, (GLsizei)renderable->GetMesh()->IndexCount(), GL_UNSIGNED_INT, 0);
}
}

if (!branchComplete && currentNode->FirstChild())
{
currentNode = currentNode->FirstChild();
}
else if (currentNode->NextSibling())
{
currentNode = currentNode->NextSibling();
branchComplete = false;
}
else
{
branchComplete = true;
currentNode = currentNode->Parent();
}
}

// for (uint8_t meshIndex = 0; meshIndex < _meshCount; meshIndex++)
// {
// glBindBuffer(GL_ARRAY_BUFFER, m_Pipeline.vbo[meshIndex]);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Pipeline.ibo[meshIndex]);

// glDrawElements(GL_TRIANGLES, (GLsizei)m_Meshes[meshIndex].IndexCount(), GL_UNSIGNED_INT, 0);
// }
}

void GraphicsApiGL::ClearFrameBuffer(float r, float g, float b)
Expand Down
3 changes: 3 additions & 0 deletions src/lepus/gfx/GraphicsEngine/GraphicsApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ namespace lepus
{
private:
bool m_ShutdownCalled;

protected:
GraphicsApiOptions* m_Options;

protected:
/// @brief Performs internal, boilerplate setup for all API wrappers.
/// @tparam TGraphicsApiOptions An options type derived from GraphicsApiOptions for a specific graphics API.
Expand All @@ -71,6 +73,7 @@ namespace lepus
/// @param name The name of the uniform to fetch.
/// @return API-specific handle for a uniform of a given type.
virtual void* GetUniformInternal(char* name) = 0;

public:
/// @brief Default constructor. Does nothing, so Init(GraphicsApiOptions*) needs to be called manually.
GraphicsApi()
Expand Down
120 changes: 120 additions & 0 deletions src/lepus/gfx/SceneGraph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#ifndef LEPUS_GFX_SCENEGRAPH
#define LEPUS_GFX_SCENEGRAPH
#include "SceneGraph/Renderable.h"

namespace lepus
{
namespace gfx
{
template<class MeshType = lepus::engine::objects::Mesh, class RenderableType = lepus::gfx::Renderable<MeshType>>
class SceneGraph
{
public:

class Node
{
private:
friend class SceneGraph;

protected:
Node* m_Sibling;
Node* m_Child;
Node* m_Parent;
const RenderableType* m_Renderable;

public:
Node()
{
m_Sibling = nullptr;
m_Child = nullptr;
m_Parent = nullptr;
m_Renderable = nullptr;
}

~Node()
{

}

inline const RenderableType* GetRenderable() const { return m_Renderable; }
inline const Node* NextSibling() const { return m_Sibling; }
inline const Node* Parent() const { return m_Parent; }
inline const Node* FirstChild() const { return m_Child; }

inline bool IsRoot() const { return Parent() == nullptr; }

inline const Node* AddChild(const RenderableType* renderable)
{
Node* currentNode = m_Child;
Node* lastChild = m_Child;
while (currentNode)
{
lastChild = currentNode;
currentNode = currentNode->m_Sibling;
}

if (!currentNode)
{
currentNode = new Node();
currentNode->m_Renderable = renderable;
currentNode->m_Parent = this;
}

if (!m_Child)
{
m_Child = currentNode;
}
else if (lastChild && !lastChild->m_Sibling)
{
lastChild->m_Sibling = currentNode;
}

return currentNode;
}
};

protected:
Node* m_Root;

public:

SceneGraph()
{
m_Root = new Node();
}

const Node* AddChild(const RenderableType* renderable)
{
return m_Root->AddChild(renderable);
}

~SceneGraph()
{
Node* currentNode = m_Root->m_Child;
Node* parent = currentNode;

// Delete all children
while (currentNode)
{
if (currentNode->m_Child)
{
parent = currentNode;
currentNode = currentNode->m_Child;
}
else
{
parent->m_Child = currentNode->m_Sibling;
delete currentNode;
currentNode = parent;
}
}
}

const Node* Root() const
{
return m_Root;
}
};
}
}
#endif
60 changes: 60 additions & 0 deletions src/lepus/gfx/SceneGraph/Renderable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef LEPUS_GFX_SCENEGRAPH_RENDERABLE
#define LEPUS_GFX_SCENEGRAPH_RENDERABLE

#include <lepus/engine/Objects/Mesh.h>
#include <lepus/utility/types/Transform.h>

namespace lepus
{
namespace gfx
{
template<class MeshType = lepus::engine::objects::Mesh>
class Renderable
{
private:
const MeshType* m_Mesh;
const lepus::math::Transform* m_Transform;
bool m_OwnsTransform;

public:
Renderable() = delete;

Renderable(const MeshType* mesh, const lepus::math::Transform& transform)
{
m_Mesh = mesh;
m_Transform = &transform;
m_OwnsTransform = false;
}

Renderable(const MeshType* mesh, lepus::math::Transform&& transform)
{
m_Mesh = mesh;
m_Transform = new lepus::math::Transform(transform);
m_OwnsTransform = true;
}

~Renderable()
{
m_Mesh = nullptr;

if (m_OwnsTransform)
{
delete m_Transform;
m_Transform = nullptr;
}
}

const MeshType* GetMesh() const
{
return m_Mesh;
}

const lepus::math::Transform& GetTransform() const
{
return *m_Transform;
}
};
}
}

#endif
29 changes: 29 additions & 0 deletions src/lepus/utility/types/Transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ namespace lepus
m_Rotation = lepus::types::Quaternion();
}

Transform(Transform&& transform)
{
m_Origin = transform.Origin();
m_Forward = transform.Forward();
m_Up = transform.Up();
m_Right = transform.Right();
m_Rotation = transform.Rotation();
}

Transform(const Transform& transform)
{
m_Origin = transform.Origin();
m_Forward = transform.Forward();
m_Up = transform.Up();
m_Right = transform.Right();
m_Rotation = transform.Rotation();
}

Transform& operator=(const Transform& transform)
{
m_Origin = transform.Origin();
m_Forward = transform.Forward();
m_Up = transform.Up();
m_Right = transform.Right();
m_Rotation = transform.Rotation();

return *this;
}

inline lepus::types::Vector3 Origin() const { return m_Origin; }
inline void Origin(const lepus::types::Vector3& vec)
{
Expand Down

0 comments on commit 05d2553

Please sign in to comment.