One hell of a GUI interface (minus graphical)
"how does this even work lol"
This commit is contained in:
+74
-27
@@ -31,17 +31,29 @@ public:
|
||||
, ResourceManager(resourceManager)
|
||||
, Rectangle()
|
||||
, m_Name("UIParent")
|
||||
{ Initialize(); }
|
||||
, m_Layer(0)
|
||||
{ }
|
||||
|
||||
// Create a frame as a child
|
||||
Frame(std::shared_ptr<Frame> parent, std::string name)
|
||||
Frame(Frame* parent, std::string name)
|
||||
: Rectangle(static_cast<Rectangle>(*parent)) // Clone parent rectangle using copy constructor
|
||||
, m_Name(name)
|
||||
{ SetParent(parent); Initialize(); }
|
||||
, m_Layer(0)
|
||||
{ SetParent(std::shared_ptr<Frame>(parent)); }
|
||||
|
||||
|
||||
::RenderQueue RenderQueue;
|
||||
|
||||
virtual void Initialize() { }
|
||||
std::shared_ptr<Frame> Parent() const { return m_Parent; }
|
||||
void SetParent(std::shared_ptr<Frame> parent)
|
||||
{
|
||||
{
|
||||
if (parent == nullptr)
|
||||
{
|
||||
LOG_ERROR("Failed to create frame \"%s\": Invalid parent", m_Name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_Layer = parent->Layer() + 1;
|
||||
parent->AddChild(std::shared_ptr<Frame>(this));
|
||||
m_Parent = parent;
|
||||
EventBroker = parent->EventBroker;
|
||||
@@ -50,25 +62,56 @@ public:
|
||||
|
||||
void AddChild(std::shared_ptr<Frame> child)
|
||||
{
|
||||
m_Children.push_back(std::make_pair(child->Name(), child));
|
||||
m_Children[child->m_Layer].insert(std::make_pair(child->Name(), child));
|
||||
if (m_Parent)
|
||||
{
|
||||
m_Parent->AddChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map<std::string, std::shared_ptr<Frame>>::const_iterator FrameChildrenIterator;
|
||||
FrameChildrenIterator begin()
|
||||
{
|
||||
return m_Children.begin();
|
||||
}
|
||||
FrameChildrenIterator end()
|
||||
{
|
||||
return m_Children.end();
|
||||
}
|
||||
|
||||
std::string Name() const { return m_Name; }
|
||||
void SetName(std::string val) { m_Name = val; }
|
||||
int Layer() const { return m_Layer; }
|
||||
|
||||
int Left() const override
|
||||
{
|
||||
if (m_Parent)
|
||||
return m_Parent->Left() + X;
|
||||
else
|
||||
return X;
|
||||
}
|
||||
int Right() const override
|
||||
{
|
||||
if (m_Parent)
|
||||
return m_Parent->Right() + X + Width;
|
||||
else
|
||||
return X + Width;
|
||||
}
|
||||
int Top() const override
|
||||
{
|
||||
if (m_Parent)
|
||||
return m_Parent->Top() + Y;
|
||||
else
|
||||
return Y;
|
||||
}
|
||||
int Bottom() const override
|
||||
{
|
||||
if (m_Parent)
|
||||
return m_Parent->Bottom() + Y + Height;
|
||||
else
|
||||
return Y + Height;
|
||||
}
|
||||
|
||||
Rectangle AbsoluteRectangle()
|
||||
{
|
||||
return Rectangle(Left(), Right(), Width, Height);
|
||||
}
|
||||
|
||||
virtual void Update(double dt)
|
||||
{
|
||||
for (auto &pair : m_Children)
|
||||
for (auto &pair : m_Children[m_Layer + 1])
|
||||
{
|
||||
pair.second->Update(dt);
|
||||
}
|
||||
@@ -76,31 +119,35 @@ public:
|
||||
|
||||
void DrawLayered(std::shared_ptr<Renderer> renderer)
|
||||
{
|
||||
renderer->SetViewport(GetLeft(), GetTop(), GetRight(), GetBottom());
|
||||
// Draw ourselves
|
||||
renderer->SetViewport(AbsoluteRectangle());
|
||||
this->Draw(renderer);
|
||||
renderer->Draw();
|
||||
|
||||
for (auto &pair : m_Children)
|
||||
// Draw children
|
||||
for (auto &pairLayer : m_Children)
|
||||
{
|
||||
pair.second->Draw(renderer);
|
||||
auto children = pairLayer.second;
|
||||
for (auto &pairChild : children)
|
||||
{
|
||||
auto child = pairChild.second;
|
||||
renderer->SetViewport(child->AbsoluteRectangle());
|
||||
child->Draw(renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Draw(std::shared_ptr<Renderer> renderer)
|
||||
{
|
||||
renderer->SetViewport(GetLeft(), GetTop(), GetRight(), GetBottom());
|
||||
renderer->Draw();
|
||||
|
||||
|
||||
}
|
||||
virtual void Draw(std::shared_ptr<Renderer> renderer) { }
|
||||
|
||||
protected:
|
||||
std::shared_ptr<::EventBroker> EventBroker;
|
||||
std::shared_ptr<::ResourceManager> ResourceManager;
|
||||
|
||||
std::string m_Name;
|
||||
int m_Layer;
|
||||
|
||||
std::shared_ptr<Frame> m_Parent;
|
||||
std::multimap<std::string, std::shared_ptr<Frame>> m_Children; // name -> frame
|
||||
typedef std::multimap<std::string, std::shared_ptr<Frame>> Children_t; // name -> frame
|
||||
std::map<int, Children_t> m_Children; // layer -> Children_t
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef GUI_GameFrame_h__
|
||||
#define GUI_GameFrame_h__
|
||||
|
||||
#include "GUI/Frame.h"
|
||||
#include "GUI/WorldFrame.h"
|
||||
#include "GUI/Viewport.h"
|
||||
|
||||
#include "GameWorld.h"
|
||||
|
||||
namespace GUI
|
||||
{
|
||||
|
||||
class GameFrame : public Frame
|
||||
{
|
||||
public:
|
||||
GameFrame(Frame* parent, std::string name)
|
||||
: Frame(parent, name)
|
||||
{
|
||||
m_World = std::make_shared<GameWorld>(EventBroker, ResourceManager);
|
||||
m_World->Initialize();
|
||||
|
||||
auto worldFrame = new WorldFrame(this, "GameWorldFrame", m_World);
|
||||
{
|
||||
new Viewport(worldFrame, "Viewport1", m_World);
|
||||
new Viewport(worldFrame, "Viewport2", m_World);
|
||||
}
|
||||
}
|
||||
|
||||
void Update(double dt) override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Draw(std::shared_ptr<Renderer> renderer) override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<GameWorld> m_World;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // GUI_GameFrame_h__
|
||||
+6
-15
@@ -13,28 +13,19 @@ public:
|
||||
TextureFrame(std::shared_ptr<Frame> parent, std::string name)
|
||||
: Frame(parent, name) { }
|
||||
|
||||
void Update(double dt) override
|
||||
{
|
||||
Frame::Update(dt);
|
||||
}
|
||||
|
||||
void Draw(std::shared_ptr<Renderer> renderer) override
|
||||
{
|
||||
if (m_Texture == nullptr)
|
||||
return;
|
||||
|
||||
RenderQueue<SpriteJob> rq;
|
||||
|
||||
auto textureAsset = ResourceManager->Load<Texture>("Texture", m_Texture);
|
||||
|
||||
RenderQueue.Clear();
|
||||
SpriteJob job;
|
||||
job.TextureID = m_Texture->ResourceID;
|
||||
job.Texture = *m_Texture;
|
||||
RenderQueue.Add(job);
|
||||
|
||||
Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity);
|
||||
glm::quat orientation2D = glm::angleAxis(glm::eulerAngles(absoluteTransform->Orientation).z, glm::vec3(0, 0, -1));
|
||||
glm::mat4 modelMatrix = glm::translate(absoluteTransform.Position);
|
||||
*glm::toMat4(orientation2D)
|
||||
* glm::scale(absoluteTransform.Scale);
|
||||
EnqueueSprite(spriteQueue, textureAsset, modelMatrix);
|
||||
renderer->SetCamera(nullptr);
|
||||
renderer->Draw(RenderQueue);
|
||||
}
|
||||
|
||||
std::shared_ptr<::Texture> Texture() const { return m_Texture; }
|
||||
|
||||
+12
-9
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "GUI/Frame.h"
|
||||
#include "World.h"
|
||||
#include "Systems/TransformSystem.h"
|
||||
#include "Components/Transform.h"
|
||||
#include "Components/Camera.h"
|
||||
#include "RenderQueue.h"
|
||||
@@ -16,10 +17,12 @@ namespace GUI
|
||||
class Viewport : public Frame
|
||||
{
|
||||
public:
|
||||
Viewport(std::shared_ptr<Frame> parent, std::string name, std::shared_ptr<World> world)
|
||||
Viewport(Frame* parent, std::string name, std::shared_ptr<World> world)
|
||||
: Frame(parent, name)
|
||||
, m_World(world)
|
||||
{ }
|
||||
{
|
||||
m_TransformSystem = m_World->GetSystem<Systems::TransformSystem>();
|
||||
}
|
||||
|
||||
EntityID CameraEntity() const { return m_CameraEntity; }
|
||||
void SetCameraEntity(EntityID cameraEntity)
|
||||
@@ -35,37 +38,37 @@ public:
|
||||
m_Camera = std::make_shared<Camera>(cameraComponent->FOV, cameraComponent->NearClip, cameraComponent->FarClip);
|
||||
}
|
||||
|
||||
void Initialize() override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Update(double dt) override
|
||||
{
|
||||
auto transformComponent = m_World->GetComponent<Components::Transform>(m_CameraEntity);
|
||||
if (!transformComponent)
|
||||
return;
|
||||
|
||||
auto cameraComponent = m_World->GetComponent<Components::Camera>(m_CameraEntity);
|
||||
if (!cameraComponent)
|
||||
return;
|
||||
|
||||
Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(m_CameraEntity);
|
||||
|
||||
m_Camera->SetFOV(cameraComponent->FOV);
|
||||
m_Camera->SetNearClip(cameraComponent->NearClip);
|
||||
m_Camera->SetFarClip(cameraComponent->FarClip);
|
||||
m_Camera->SetPosition(absoluteTransform.Position);
|
||||
m_Camera->SetOrientation(absoluteTransform.Orientation);
|
||||
}
|
||||
|
||||
void Draw(std::shared_ptr<Renderer> renderer) override
|
||||
{
|
||||
renderer->SetCamera(m_Camera);
|
||||
|
||||
Frame::Draw(renderer);
|
||||
renderer->Draw(m_Parent->RenderQueue);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<World> m_World;
|
||||
std::shared_ptr<Systems::TransformSystem> m_TransformSystem;
|
||||
std::shared_ptr<Camera> m_Camera;
|
||||
EntityID m_CameraEntity;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+95
-101
@@ -15,129 +15,123 @@
|
||||
namespace GUI
|
||||
{
|
||||
|
||||
class WorldFrame : public Frame
|
||||
class WorldFrame : public Frame
|
||||
{
|
||||
public:
|
||||
WorldFrame(Frame* parent, std::string name, std::shared_ptr<World> world)
|
||||
: Frame(parent, name)
|
||||
, m_World(world)
|
||||
{
|
||||
public:
|
||||
WorldFrame(std::shared_ptr<Frame> parent, std::string name, std::shared_ptr<World> world)
|
||||
: Frame(parent, name)
|
||||
, m_World(world)
|
||||
{ }
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetViewportCamera, &WorldFrame::OnSetViewportCamera);
|
||||
m_TransformSystem = m_World->GetSystem<Systems::TransformSystem>();
|
||||
}
|
||||
|
||||
void Initialize() override
|
||||
void Update(double dt) override
|
||||
{
|
||||
m_World->Update(dt);
|
||||
}
|
||||
|
||||
void Draw(std::shared_ptr<Renderer> renderer) override
|
||||
{
|
||||
RenderQueue.Clear();
|
||||
|
||||
for (auto &pair : *m_World->GetEntities())
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetViewportCamera, &WorldFrame::OnSetViewportCamera);
|
||||
EntityID entity = pair.first;
|
||||
|
||||
m_World->Initialize();
|
||||
}
|
||||
auto transform = m_World->GetComponent<Components::Transform>(entity);
|
||||
if (!transform)
|
||||
continue;
|
||||
|
||||
void Update(double dt) override
|
||||
{
|
||||
m_World->Update(dt);
|
||||
m_TransformSystem = m_World->GetSystem<Systems::TransformSystem>();
|
||||
}
|
||||
|
||||
void Draw(std::shared_ptr<Renderer> renderer) override
|
||||
{
|
||||
renderer->Flush();
|
||||
|
||||
RenderQueue<ModelJob> modelQueue;
|
||||
RenderQueue<SpriteJob> spriteQueue;
|
||||
for (auto &pair : *m_World->GetEntities())
|
||||
auto modelComponent = m_World->GetComponent<Components::Model>(entity);
|
||||
if (modelComponent)
|
||||
{
|
||||
EntityID entity = pair.first;
|
||||
|
||||
auto transform = m_World->GetComponent<Components::Transform>(entity);
|
||||
if (!transform)
|
||||
continue;
|
||||
|
||||
auto modelComponent = m_World->GetComponent<Components::Model>(entity);
|
||||
if (modelComponent)
|
||||
auto modelAsset = ResourceManager->Load<Model>("Model", modelComponent->ModelFile);
|
||||
if (modelAsset)
|
||||
{
|
||||
auto modelAsset = ResourceManager->Load<Model>("Model", modelComponent->ModelFile);
|
||||
if (modelAsset)
|
||||
{
|
||||
Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity);
|
||||
glm::mat4 modelMatrix = glm::translate(glm::mat4(), absoluteTransform.Position)
|
||||
* glm::toMat4(absoluteTransform.Orientation)
|
||||
* glm::scale(absoluteTransform.Scale);
|
||||
EnqueueModel(modelQueue, modelAsset, modelMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
auto spriteComponent = m_World->GetComponent<Components::Sprite>(entity);
|
||||
if (spriteComponent)
|
||||
{
|
||||
auto textureAsset = ResourceManager->Load<Texture>("Texture", spriteComponent->SpriteFile);
|
||||
if (textureAsset)
|
||||
{
|
||||
Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity);
|
||||
glm::quat orientation2D = glm::angleAxis(glm::eulerAngles(absoluteTransform->Orientation).z, glm::vec3(0, 0, -1));
|
||||
glm::mat4 modelMatrix = glm::translate(absoluteTransform.Position);
|
||||
* glm::toMat4(orientation2D)
|
||||
* glm::scale(absoluteTransform.Scale);
|
||||
EnqueueSprite(spriteQueue, textureAsset, modelMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
auto pointLightComponent = m_World->GetComponent<Components::PointLight>(entity);
|
||||
if (pointLightComponent)
|
||||
{
|
||||
// TODO: Push lights to renderer
|
||||
// renderer->PushLight(...);
|
||||
Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity);
|
||||
glm::mat4 modelMatrix = glm::translate(glm::mat4(), absoluteTransform.Position)
|
||||
* glm::toMat4(absoluteTransform.Orientation)
|
||||
* glm::scale(absoluteTransform.Scale);
|
||||
EnqueueModel(modelAsset, modelMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
renderer->PushQueue(rq);
|
||||
|
||||
Frame::Draw(renderer);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<World> m_World;
|
||||
|
||||
private:
|
||||
EventRelay<Frame, Events::SetViewportCamera> m_ESetViewportCamera;
|
||||
bool OnSetViewportCamera(const Events::SetViewportCamera &event)
|
||||
{
|
||||
auto itpair = m_Children.equal_range(event.ViewportFrame);
|
||||
for (auto it = itpair.first; it != itpair.second; ++it)
|
||||
auto spriteComponent = m_World->GetComponent<Components::Sprite>(entity);
|
||||
if (spriteComponent)
|
||||
{
|
||||
auto viewportFrame = std::dynamic_pointer_cast<GUI::Viewport>(it->second);
|
||||
if (!viewportFrame)
|
||||
continue;
|
||||
auto textureAsset = ResourceManager->Load<Texture>("Texture", spriteComponent->SpriteFile);
|
||||
if (textureAsset)
|
||||
{
|
||||
Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity);
|
||||
glm::quat orientation2D = glm::angleAxis(glm::eulerAngles(absoluteTransform.Orientation).z, glm::vec3(0, 0, -1));
|
||||
glm::mat4 modelMatrix = glm::translate(absoluteTransform.Position)
|
||||
* glm::toMat4(orientation2D)
|
||||
* glm::scale(absoluteTransform.Scale);
|
||||
EnqueueSprite(textureAsset, modelMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
viewportFrame->SetCamera(event.CameraEntity);
|
||||
auto pointLightComponent = m_World->GetComponent<Components::PointLight>(entity);
|
||||
if (pointLightComponent)
|
||||
{
|
||||
// TODO: Push lights to renderer
|
||||
// renderer->PushLight(...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Systems::TransformSystem> m_TransformSystem;
|
||||
protected:
|
||||
std::shared_ptr<World> m_World;
|
||||
|
||||
void EnqueueModel(RenderQueue<ModelJob> &renderQueue, Model* model, glm::mat4 modelMatrix)
|
||||
private:
|
||||
EventRelay<Frame, Events::SetViewportCamera> m_ESetViewportCamera;
|
||||
bool OnSetViewportCamera(const Events::SetViewportCamera &event)
|
||||
{
|
||||
// Search next layer for viewports and update cameras
|
||||
auto itpair = m_Children[m_Layer + 1].equal_range(event.ViewportFrame);
|
||||
for (auto it = itpair.first; it != itpair.second; ++it)
|
||||
{
|
||||
for (auto texGroup : model->TextureGroups)
|
||||
{
|
||||
ModelJob job;
|
||||
job.TextureID = texGroup.Texture->ResourceID;
|
||||
job.DiffuseTexture = *texGroup.Texture;
|
||||
job.NormalTexture = *texGroup.NormalMap;
|
||||
job.SpecularTexture = *texGroup.SpecularMap;
|
||||
job.VAO = model->VAO;
|
||||
job.StartIndex = texGroup.StartIndex;
|
||||
job.EndIndex = texGroup.EndIndex;
|
||||
job.ModelMatrix = modelMatrix;
|
||||
|
||||
renderQueue.Add(job);
|
||||
}
|
||||
auto viewportFrame = std::dynamic_pointer_cast<GUI::Viewport>(it->second);
|
||||
if (!viewportFrame)
|
||||
continue;
|
||||
|
||||
viewportFrame->SetCameraEntity(event.CameraEntity);
|
||||
}
|
||||
|
||||
void EnqueueSprite(RenderQueue<SpriteJob> &renderQueue, Texture* texture, glm::mat4 modelMatrix)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Systems::TransformSystem> m_TransformSystem;
|
||||
|
||||
void EnqueueModel(Model* model, glm::mat4 modelMatrix)
|
||||
{
|
||||
for (auto texGroup : model->TextureGroups)
|
||||
{
|
||||
SpriteJob job;
|
||||
job.TextureID = texture->ResourceID;
|
||||
job.Texture = *texture;
|
||||
ModelJob job;
|
||||
job.TextureID = texGroup.Texture->ResourceID;
|
||||
job.DiffuseTexture = *texGroup.Texture;
|
||||
job.NormalTexture = (texGroup.NormalMap) ? *texGroup.NormalMap : 0;
|
||||
job.SpecularTexture = (texGroup.SpecularMap) ? *texGroup.SpecularMap : 0;
|
||||
job.VAO = model->VAO;
|
||||
job.StartIndex = texGroup.StartIndex;
|
||||
job.EndIndex = texGroup.EndIndex;
|
||||
job.ModelMatrix = modelMatrix;
|
||||
|
||||
RenderQueue.Add(job);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void EnqueueSprite(Texture* texture, glm::mat4 modelMatrix)
|
||||
{
|
||||
SpriteJob job;
|
||||
job.TextureID = texture->ResourceID;
|
||||
job.Texture = *texture;
|
||||
job.ModelMatrix = modelMatrix;
|
||||
|
||||
RenderQueue.Add(job);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user