@@ -10,6 +10,7 @@ Libraries bundled along with binaries for Windows (MSVC14), available as a submo
|
|||||||
| **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) |
|
| **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) |
|
||||||
| **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) |
|
| **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) |
|
||||||
| **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
|
| **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
|
||||||
|
| **[ImGui](https://github.com/ocornut/imgui)** | 2015-12-12 | [MIT License](https://github.com/ocornut/imgui/blob/de3a154f3801de22c8e0bd2aeabf663a70c05972/LICENSE) |
|
||||||
|
|
||||||
#### External libraries
|
#### External libraries
|
||||||
Libraries that are too big to be bundled with the project.
|
Libraries that are too big to be bundled with the project.
|
||||||
|
|||||||
+1
-1
Submodule assets updated: b37468222e...95823e122a
+1
-1
Submodule deps updated: 1b478d3159...f20b9cc13b
@@ -54,6 +54,8 @@ public:
|
|||||||
ComponentWrapper Allocate(EntityID entity);
|
ComponentWrapper Allocate(EntityID entity);
|
||||||
// Get the component belonging to a specific entity
|
// Get the component belonging to a specific entity
|
||||||
ComponentWrapper GetByEntity(EntityID ent);
|
ComponentWrapper GetByEntity(EntityID ent);
|
||||||
|
// Returns true if the pool contains a component for the specified entity
|
||||||
|
bool KnowsEntity(EntityID ent);
|
||||||
// Delete a component and free its memory
|
// Delete a component and free its memory
|
||||||
void Delete(ComponentWrapper& wrapper);
|
void Delete(ComponentWrapper& wrapper);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef Events_KeyboardChar_h__
|
||||||
|
#define Events_KeyboardChar_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct KeyboardChar : Event
|
||||||
|
{
|
||||||
|
double Timestamp = 0.f;
|
||||||
|
unsigned int Char = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef Events_MouseScroll_h__
|
||||||
|
#define Events_MouseScroll_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct MouseScroll : Event
|
||||||
|
{
|
||||||
|
double DeltaX;
|
||||||
|
double DeltaY;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -8,9 +8,11 @@
|
|||||||
#include "EventBroker.h"
|
#include "EventBroker.h"
|
||||||
#include "EKeyDown.h"
|
#include "EKeyDown.h"
|
||||||
#include "EKeyUp.h"
|
#include "EKeyUp.h"
|
||||||
|
#include "EKeyboardChar.h"
|
||||||
#include "EMousePress.h"
|
#include "EMousePress.h"
|
||||||
#include "EMouseRelease.h"
|
#include "EMouseRelease.h"
|
||||||
#include "EMouseMove.h"
|
#include "EMouseMove.h"
|
||||||
|
#include "EMouseScroll.h"
|
||||||
#include "ELockMouse.h"
|
#include "ELockMouse.h"
|
||||||
#include "EGamepadAxis.h"
|
#include "EGamepadAxis.h"
|
||||||
#include "EGamepadButton.h"
|
#include "EGamepadButton.h"
|
||||||
@@ -64,6 +66,11 @@ private:
|
|||||||
|
|
||||||
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
|
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
|
||||||
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
|
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
|
||||||
|
|
||||||
|
static std::vector<unsigned int> GLFWCharCallbackQueue;
|
||||||
|
static void GLFWCharCallback(GLFWwindow* window, unsigned int c);
|
||||||
|
static std::vector<std::pair<double, double>> GLFWScrollCallbackQueue;
|
||||||
|
static void GLFWScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,19 +7,39 @@
|
|||||||
|
|
||||||
class System
|
class System
|
||||||
{
|
{
|
||||||
friend class SystemPipeline;
|
protected:
|
||||||
|
System(EventBroker* eventBroker)
|
||||||
public:
|
|
||||||
System(EventBroker* eventBroker, std::string componentType)
|
|
||||||
: m_EventBroker(eventBroker)
|
: m_EventBroker(eventBroker)
|
||||||
, m_ComponentType(componentType)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string m_ComponentType;
|
|
||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PureSystem : public System
|
||||||
|
{
|
||||||
|
friend class SystemPipeline;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PureSystem(EventBroker* eventBroker, std::string componentType)
|
||||||
|
: System(eventBroker)
|
||||||
|
, m_ComponentType(componentType)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
const std::string m_ComponentType;
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& component, double dt) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImpureSystem : public System
|
||||||
|
{
|
||||||
|
friend class SystemPipeline;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ImpureSystem(EventBroker* eventBroker)
|
||||||
|
: System(eventBroker)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void Update(World* world, double dt) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -14,7 +14,7 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
~SystemPipeline()
|
~SystemPipeline()
|
||||||
{
|
{
|
||||||
for (auto& pair : m_Systems) {
|
for (auto& pair : m_PureSystems) {
|
||||||
for (auto& system : pair.second) {
|
for (auto& system : pair.second) {
|
||||||
delete system;
|
delete system;
|
||||||
}
|
}
|
||||||
@@ -25,17 +25,32 @@ public:
|
|||||||
void AddSystem(Arguments... args)
|
void AddSystem(Arguments... args)
|
||||||
{
|
{
|
||||||
System* system = new T(m_EventBroker, args...);
|
System* system = new T(m_EventBroker, args...);
|
||||||
if (!system->m_ComponentType.empty()) {
|
m_Systems[typeid(T).name()] = system;
|
||||||
m_Systems[system->m_ComponentType].push_back(system);
|
|
||||||
} else {
|
if (std::is_base_of<PureSystem, T>::value) {
|
||||||
LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name());
|
PureSystem* pureSystem = static_cast<PureSystem*>(system);
|
||||||
delete system;
|
if (!pureSystem->m_ComponentType.empty()) {
|
||||||
|
m_PureSystems[pureSystem->m_ComponentType].push_back(pureSystem);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::is_base_of<ImpureSystem, T>::value) {
|
||||||
|
ImpureSystem* impureSystem = static_cast<ImpureSystem*>(system);
|
||||||
|
m_ImpureSystems.push_back(impureSystem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(World* world, double dt)
|
void Update(World* world, double dt)
|
||||||
{
|
{
|
||||||
|
// Process events
|
||||||
for (auto& pair : m_Systems) {
|
for (auto& pair : m_Systems) {
|
||||||
|
m_EventBroker->Process(pair.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
for (auto& pair : m_PureSystems) {
|
||||||
const std::string& componentName = pair.first;
|
const std::string& componentName = pair.first;
|
||||||
auto& systems = pair.second;
|
auto& systems = pair.second;
|
||||||
const ComponentPool* pool = world->GetComponents(componentName);
|
const ComponentPool* pool = world->GetComponents(componentName);
|
||||||
@@ -44,15 +59,20 @@ public:
|
|||||||
}
|
}
|
||||||
for (auto& component : *pool) {
|
for (auto& component : *pool) {
|
||||||
for (auto& system : systems) {
|
for (auto& system : systems) {
|
||||||
system->Update(world, component, dt);
|
system->UpdateComponent(world, component, dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto& system : m_ImpureSystems) {
|
||||||
|
system->Update(world, dt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
std::unordered_map<std::string, std::vector<System*>> m_Systems;
|
std::map<std::string, System*> m_Systems;
|
||||||
|
std::map<std::string, std::vector<PureSystem*>> m_PureSystems;
|
||||||
|
std::vector<ImpureSystem*> m_ImpureSystems;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -14,17 +14,27 @@ public:
|
|||||||
|
|
||||||
// Create empty entity
|
// Create empty entity
|
||||||
EntityID CreateEntity(EntityID parent = 0);
|
EntityID CreateEntity(EntityID parent = 0);
|
||||||
|
// Delete entity and all components within
|
||||||
|
void DeleteEntity(EntityID entity);
|
||||||
|
|
||||||
// Register a component type and allocate space for it
|
// Register a component type and allocate space for it
|
||||||
void RegisterComponent(ComponentInfo& ci);
|
void RegisterComponent(ComponentInfo& ci);
|
||||||
// Attach a component to an entity and fill it with default values
|
// Attach a component to an entity and fill it with default values
|
||||||
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
|
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
|
||||||
|
// Check if an entity has a component
|
||||||
|
bool HasComponent(EntityID entity, std::string componentType);
|
||||||
// Get a component of an entity
|
// Get a component of an entity
|
||||||
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
||||||
|
// Delete a component off an entity
|
||||||
|
void DeleteComponent(EntityID entity, std::string componentType);
|
||||||
// Get all components of the specified type
|
// Get all components of the specified type
|
||||||
const ComponentPool* GetComponents(std::string componentType);
|
const ComponentPool* GetComponents(std::string componentType);
|
||||||
// Get entity parent
|
// Get entity parent
|
||||||
EntityID GetParent(EntityID entity);
|
EntityID GetParent(EntityID entity);
|
||||||
|
// Get all component pools
|
||||||
|
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
|
||||||
|
// Get the entity children map
|
||||||
|
const std::unordered_multimap<EntityID, EntityID>& GetEntityChildren() const { return m_EntityChildren; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EntityID m_CurrentEntityID = 1;
|
EntityID m_CurrentEntityID = 1;
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include <glm/gtx/common.hpp>
|
||||||
|
#include "../Core/System.h"
|
||||||
|
#include "../Core/EMousePress.h"
|
||||||
|
#include "../Core/ConfigFile.h"
|
||||||
|
#include "../Input/EInputCommand.h"
|
||||||
|
#include "../Rendering/EPicking.h"
|
||||||
|
#include "../Rendering/RenderQueueFactory.h"
|
||||||
|
|
||||||
|
class EditorSystem : public ImpureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorSystem(EventBroker* eventBroker);
|
||||||
|
|
||||||
|
virtual void Update(World* world, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_Enabled;
|
||||||
|
bool m_Visible;
|
||||||
|
std::vector<glm::vec2> m_PickingQueue;
|
||||||
|
EntityID m_Widget = 0;
|
||||||
|
EntityID m_Selection = 0;
|
||||||
|
EntityID m_LastSelection = 0;
|
||||||
|
glm::vec3 m_Position;
|
||||||
|
|
||||||
|
EventRelay<EditorSystem, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
|
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
|
||||||
|
bool OnMousePress(const Events::MousePress& e);
|
||||||
|
EventRelay<EditorSystem, Events::Picking> m_EPicking;
|
||||||
|
bool OnPicking(const Events::Picking& e);
|
||||||
|
|
||||||
|
void drawUI(World* world, double dt);
|
||||||
|
bool createDeleteButton(std::string componentType);
|
||||||
|
};
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <imgui/imgui.h>
|
||||||
#include "../Input/FirstPersonInputController.h"
|
#include "../Input/FirstPersonInputController.h"
|
||||||
|
|
||||||
template <typename EventContext>
|
template <typename EventContext>
|
||||||
@@ -13,22 +14,35 @@ public:
|
|||||||
|
|
||||||
virtual bool OnCommand(const Events::InputCommand& e) override
|
virtual bool OnCommand(const Events::InputCommand& e) override
|
||||||
{
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
if (e.Command == "PrimaryFire") {
|
if (e.Command == "PrimaryFire") {
|
||||||
if (e.Value > 0) {
|
if (e.Value > 0) {
|
||||||
LockMouse();
|
if (!io.WantCaptureMouse) {
|
||||||
|
LockMouse();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
UnlockMouse();
|
UnlockMouse();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Command == "Right") {
|
if (!io.WantCaptureKeyboard) {
|
||||||
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
if (e.Command == "Right") {
|
||||||
m_Velocity.x = value;
|
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
||||||
}
|
m_Velocity.x = value;
|
||||||
if (e.Command == "Forward") {
|
}
|
||||||
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
if (e.Command == "Forward") {
|
||||||
m_Velocity.z = -value;
|
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
||||||
|
m_Velocity.z = -value;
|
||||||
|
}
|
||||||
|
if (e.Command == "Sprint") {
|
||||||
|
if (e.Value > 0.f) {
|
||||||
|
m_Speed = m_BaseSpeed * 2.f * (e.Value);
|
||||||
|
} else {
|
||||||
|
m_Speed = m_BaseSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FirstPersonInputController::OnCommand(e);
|
return FirstPersonInputController::OnCommand(e);
|
||||||
@@ -37,12 +51,13 @@ public:
|
|||||||
void Update(double dt)
|
void Update(double dt)
|
||||||
{
|
{
|
||||||
if (glm::length2(m_Velocity) > 0) {
|
if (glm::length2(m_Velocity) > 0) {
|
||||||
m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_BaseSpeed);
|
m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 m_Position = glm::vec3(0, 0, 0);
|
glm::vec3 m_Position = glm::vec3(0, 0, 0);
|
||||||
glm::vec3 m_Velocity = glm::vec3(0, 0, 0);
|
glm::vec3 m_Velocity = glm::vec3(0, 0, 0);
|
||||||
float m_BaseSpeed = 0.1f;
|
float m_BaseSpeed = 2.0f;
|
||||||
|
float m_Speed = m_BaseSpeed;
|
||||||
};
|
};
|
||||||
@@ -40,15 +40,17 @@ public:
|
|||||||
{
|
{
|
||||||
PickData pickData;
|
PickData pickData;
|
||||||
|
|
||||||
|
// Invert screen y coordinate
|
||||||
|
screenCoord.y = Resolution.Height - screenCoord.y;
|
||||||
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer);
|
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer);
|
||||||
|
|
||||||
auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1]));
|
auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1]));
|
||||||
if (it != PickingColorsToEntity->end()) {
|
if (it != PickingColorsToEntity->end()) {
|
||||||
pickData.Entity = it->second;
|
pickData.Entity = it->second;
|
||||||
} else {
|
} else {
|
||||||
pickData.Entity = -1;
|
pickData.Entity = 0;
|
||||||
}
|
}
|
||||||
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, Resolution.Width - screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);
|
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);
|
||||||
|
|
||||||
return pickData;
|
return pickData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include "../OpenGL.h"
|
||||||
|
#include "IRenderer.h"
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "../Core/EMousePress.h"
|
||||||
|
#include "../Core/EMouseRelease.h"
|
||||||
|
#include "../Core/EMouseMove.h"
|
||||||
|
#include "../Core/EMouseScroll.h"
|
||||||
|
#include "../Core/EKeyDown.h"
|
||||||
|
#include "../Core/EKeyUp.h"
|
||||||
|
#include "../Core/EKeyboardChar.h"
|
||||||
|
|
||||||
|
class ImGuiRenderPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker);
|
||||||
|
|
||||||
|
void Update(double dt);
|
||||||
|
void Draw();
|
||||||
|
|
||||||
|
private:
|
||||||
|
IRenderer* m_Renderer;
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
|
GLFWwindow* g_Window;
|
||||||
|
double g_DeltaTime = 0.0;
|
||||||
|
float g_MouseWheel = 0.f;
|
||||||
|
GLuint g_FontTexture;
|
||||||
|
int g_ShaderHandle;
|
||||||
|
int g_VertHandle;
|
||||||
|
int g_FragHandle;
|
||||||
|
int g_AttribLocationTex;
|
||||||
|
int g_AttribLocationProjMtx;
|
||||||
|
int g_AttribLocationPosition;
|
||||||
|
int g_AttribLocationUV;
|
||||||
|
int g_AttribLocationColor;
|
||||||
|
GLuint g_VboHandle;
|
||||||
|
GLuint g_VaoHandle;
|
||||||
|
GLuint g_ElementsHandle;
|
||||||
|
|
||||||
|
EventRelay<ImGuiRenderPass, Events::MousePress> m_EMousePress;
|
||||||
|
bool OnMousePress(const Events::MousePress& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::MouseRelease> m_EMouseRelease;
|
||||||
|
bool OnMouseRelease(const Events::MouseRelease& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::MouseMove> m_EMouseMove;
|
||||||
|
bool OnMouseMove(const Events::MouseMove& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::MouseScroll> m_EMouseScroll;
|
||||||
|
bool OnMouseScroll(const Events::MouseScroll& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::KeyDown> m_EKeyDown;
|
||||||
|
bool OnKeyDown(const Events::KeyDown& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::KeyUp> m_EKeyUp;
|
||||||
|
bool OnKeyUp(const Events::KeyUp& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::KeyboardChar> m_EKeyboardChar;
|
||||||
|
bool OnKeyboardChar(const Events::KeyboardChar& e);
|
||||||
|
|
||||||
|
bool createDeviceObjects();
|
||||||
|
bool createFontsTexture();
|
||||||
|
|
||||||
|
void newFrame();
|
||||||
|
};
|
||||||
@@ -13,8 +13,12 @@ public:
|
|||||||
RenderQueueFactory();
|
RenderQueueFactory();
|
||||||
void Update(World* world);
|
void Update(World* world);
|
||||||
|
|
||||||
|
|
||||||
RenderQueueCollection RenderQueues() const { return m_RenderQueues; }
|
RenderQueueCollection RenderQueues() const { return m_RenderQueues; }
|
||||||
|
|
||||||
|
static glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
||||||
|
static glm::quat AbsoluteOrientation(World* world, EntityID entity);
|
||||||
|
static glm::vec3 AbsoluteScale(World* world, EntityID entity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RenderQueueCollection m_RenderQueues;
|
RenderQueueCollection m_RenderQueues;
|
||||||
|
|
||||||
@@ -22,10 +26,6 @@ private:
|
|||||||
void FillLights(World* world, RenderQueue* renderQueue);
|
void FillLights(World* world, RenderQueue* renderQueue);
|
||||||
|
|
||||||
glm::mat4 ModelMatrix(World* world, EntityID entity);
|
glm::mat4 ModelMatrix(World* world, EntityID entity);
|
||||||
|
|
||||||
glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
|
||||||
glm::quat AbsoluteOrientation(World* world, EntityID entity);
|
|
||||||
glm::vec3 AbsoluteScale(World* world, EntityID entity);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -28,6 +28,7 @@ enum lightType
|
|||||||
|
|
||||||
#include "../Core/EventBroker.h"
|
#include "../Core/EventBroker.h"
|
||||||
#include "EPicking.h"
|
#include "EPicking.h"
|
||||||
|
#include "ImGuiRenderPass.h"
|
||||||
|
|
||||||
class Renderer : public IRenderer
|
class Renderer : public IRenderer
|
||||||
{
|
{
|
||||||
@@ -54,6 +55,7 @@ private:
|
|||||||
|
|
||||||
DrawScenePass* m_DrawScenePass;
|
DrawScenePass* m_DrawScenePass;
|
||||||
PickingPass* m_PickingPass;
|
PickingPass* m_PickingPass;
|
||||||
|
ImGuiRenderPass* m_ImGuiRenderPass;
|
||||||
|
|
||||||
//----------------------Functions----------------------//
|
//----------------------Functions----------------------//
|
||||||
void InitializeWindow();
|
void InitializeWindow();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "Core/SystemPipeline.h"
|
#include "Core/SystemPipeline.h"
|
||||||
#include "RaptorCopterSystem.h"
|
#include "RaptorCopterSystem.h"
|
||||||
#include "PlayerSystem.h"
|
#include "PlayerSystem.h"
|
||||||
|
#include "Editor/EditorSystem.h"
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,17 +18,17 @@ struct KeyInput
|
|||||||
bool Right = false;
|
bool Right = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayerSystem : public System
|
class PlayerSystem : public PureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlayerSystem(EventBroker* eventBroker)
|
PlayerSystem(EventBroker* eventBroker)
|
||||||
: System(eventBroker, "Player")
|
: PureSystem(eventBroker, "Player")
|
||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown);
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp);
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Update(World* world, ComponentWrapper& player, double dt) override;
|
virtual void UpdateComponent(World* world, ComponentWrapper& player, double dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float m_Speed = 5;
|
float m_Speed = 5;
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
|
|
||||||
class RaptorCopterSystem : public System
|
class RaptorCopterSystem : public PureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RaptorCopterSystem(EventBroker* eventBroker)
|
RaptorCopterSystem(EventBroker* eventBroker)
|
||||||
: System(eventBroker, "RaptorCopter")
|
: PureSystem(eventBroker, "RaptorCopter")
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void Initialize() { }
|
virtual void UpdateComponent(World* world, ComponentWrapper& raptorCopter, double dt) override
|
||||||
|
|
||||||
virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override
|
|
||||||
{
|
{
|
||||||
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
|
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
|
||||||
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"];
|
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"];
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
<c:Test>
|
|
||||||
<Integer>1</Integer>
|
|
||||||
<Float>1.333</Float>
|
|
||||||
<Vector X="1.33333" Y="2.33333" Z="3.33333"/>
|
|
||||||
<Quaternion X="1.33333" Y="2.33333" Z="3.33333" W="4.44444"/>
|
|
||||||
</c:Test>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
|
||||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
|
||||||
|
|
||||||
<xs:element name="Test">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>ECS Test Component</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:all>
|
|
||||||
<xs:element name="Integer" type="t:int" minOccurs="0"/>
|
|
||||||
<xs:element name="Double" type="t:double" minOccurs="0"/>
|
|
||||||
<xs:element name="String" type="t:string" minOccurs="0"/>
|
|
||||||
<xs:element name="Vector" type="t:Vector" minOccurs="0"/>
|
|
||||||
<xs:element name="Quaternion" type="t:Quaternion" minOccurs="0"/>
|
|
||||||
</xs:all>
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:schema>
|
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<Entity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd" xmlns:c="components">
|
||||||
|
<Components>
|
||||||
|
<c:Transform></c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0"/>
|
||||||
|
<Scale X="100" Y="1" Z="100"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitPlane.obj</Resource>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="1" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>An error</Resource>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
@@ -60,7 +60,6 @@ file(GLOB SOURCE_FILES_Rendering_Util
|
|||||||
"${INCLUDE_PATH}/Rendering/Util/*.h"
|
"${INCLUDE_PATH}/Rendering/Util/*.h"
|
||||||
"Rendering/Util/*.cpp"
|
"Rendering/Util/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(Rendering FILES ${SOURCE_FILES_Rendering})
|
source_group(Rendering FILES ${SOURCE_FILES_Rendering})
|
||||||
source_group(Rendering\\Util FILES ${SOURCE_FILES_Rendering_Util})
|
source_group(Rendering\\Util FILES ${SOURCE_FILES_Rendering_Util})
|
||||||
|
|
||||||
@@ -70,6 +69,12 @@ file(GLOB SOURCE_FILES_GUI
|
|||||||
)
|
)
|
||||||
source_group(GUI FILES ${SOURCE_FILES_GUI})
|
source_group(GUI FILES ${SOURCE_FILES_GUI})
|
||||||
|
|
||||||
|
file(GLOB SOURCE_FILES_Editor
|
||||||
|
"${INCLUDE_PATH}/Editor/*.h"
|
||||||
|
"Editor/*.cpp"
|
||||||
|
)
|
||||||
|
source_group(Editor FILES ${SOURCE_FILES_Editor})
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
${SOURCE_FILES_Core}
|
${SOURCE_FILES_Core}
|
||||||
${SOURCE_FILES_Core_Util}
|
${SOURCE_FILES_Core_Util}
|
||||||
@@ -78,6 +83,10 @@ set(SOURCE_FILES
|
|||||||
${SOURCE_FILES_GUI}
|
${SOURCE_FILES_GUI}
|
||||||
${SOURCE_FILES_Rendering}
|
${SOURCE_FILES_Rendering}
|
||||||
${SOURCE_FILES_Rendering_Util}
|
${SOURCE_FILES_Rendering_Util}
|
||||||
|
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_draw.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_demo.cpp
|
||||||
|
${SOURCE_FILES_Editor}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBRARIES
|
set(LIBRARIES
|
||||||
@@ -103,4 +112,4 @@ target_link_libraries(Engine
|
|||||||
${LIBRARIES}
|
${LIBRARIES}
|
||||||
)
|
)
|
||||||
#set_target_properties(Engine PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${INCLUDE_PATH}/PrecompiledHeader.h")
|
#set_target_properties(Engine PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${INCLUDE_PATH}/PrecompiledHeader.h")
|
||||||
#cotire(Engine)
|
#cotire(Engine)
|
||||||
|
|||||||
@@ -50,10 +50,16 @@ ComponentWrapper ComponentPool::GetByEntity(EntityID ent)
|
|||||||
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent));
|
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ComponentPool::KnowsEntity(EntityID ent)
|
||||||
|
{
|
||||||
|
return m_EntityToComponent.find(ent) != m_EntityToComponent.end();
|
||||||
|
}
|
||||||
|
|
||||||
void ComponentPool::Delete(ComponentWrapper& wrapper)
|
void ComponentPool::Delete(ComponentWrapper& wrapper)
|
||||||
{
|
{
|
||||||
m_EntityToComponent.erase(wrapper.EntityID);
|
m_EntityToComponent.erase(wrapper.EntityID);
|
||||||
m_Pool.Free(wrapper.Data);
|
m_Pool.Free(wrapper.Data - sizeof(EntityID));
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentPool::iterator ComponentPool::begin() const
|
ComponentPool::iterator ComponentPool::begin() const
|
||||||
|
|||||||
@@ -415,6 +415,7 @@ std::size_t EntityXMLFile::getTypeStride(std::string typeName)
|
|||||||
std::map<std::string, size_t> typeStrides{
|
std::map<std::string, size_t> typeStrides{
|
||||||
{ "bool", sizeof(bool) },
|
{ "bool", sizeof(bool) },
|
||||||
{ "int", sizeof(int) },
|
{ "int", sizeof(int) },
|
||||||
|
{ "float", sizeof(float) },
|
||||||
{ "double", sizeof(double) },
|
{ "double", sizeof(double) },
|
||||||
{ "string", sizeof(std::string) },
|
{ "string", sizeof(std::string) },
|
||||||
{ "Vector", sizeof(glm::vec3) },
|
{ "Vector", sizeof(glm::vec3) },
|
||||||
@@ -443,39 +444,52 @@ void EntityXMLFile::writeData(const xercesc::DOMElement* element, std::string ty
|
|||||||
{
|
{
|
||||||
using namespace xercesc;
|
using namespace xercesc;
|
||||||
|
|
||||||
XSValue::DataType dataType = XSValue::getDataType(XSTR(typeName.c_str()));
|
if (typeName == "Vector") {
|
||||||
if (dataType == XSValue::DataType::dt_MAXCOUNT) {
|
glm::vec3 vec;
|
||||||
if (typeName == "Vector") {
|
vec.x = getFloatAttribute(element, "X");
|
||||||
glm::vec3 vec;
|
vec.y = getFloatAttribute(element, "Y");
|
||||||
vec.x = getFloatAttribute(element, "X");
|
vec.z = getFloatAttribute(element, "Z");
|
||||||
vec.y = getFloatAttribute(element, "Y");
|
memcpy(outData, reinterpret_cast<char*>(&vec), getTypeStride(typeName));
|
||||||
vec.z = getFloatAttribute(element, "Z");
|
} else if (typeName == "Color") {
|
||||||
memcpy(outData, reinterpret_cast<char*>(&vec), getTypeStride(typeName));
|
glm::vec4 vec;
|
||||||
} else if (typeName == "Color") {
|
vec.r = getFloatAttribute(element, "R");
|
||||||
glm::vec4 vec;
|
vec.g = getFloatAttribute(element, "G");
|
||||||
vec.r = getFloatAttribute(element, "R");
|
vec.b = getFloatAttribute(element, "B");
|
||||||
vec.g = getFloatAttribute(element, "G");
|
vec.a = getFloatAttribute(element, "A");
|
||||||
vec.b = getFloatAttribute(element, "B");
|
memcpy(outData, reinterpret_cast<char*>(&vec), getTypeStride(typeName));
|
||||||
vec.a = getFloatAttribute(element, "A");
|
} else if (typeName == "Quaternion") {
|
||||||
memcpy(outData, reinterpret_cast<char*>(&vec), getTypeStride(typeName));
|
glm::quat q;
|
||||||
} else if (typeName == "Quaternion") {
|
q.x = getFloatAttribute(element, "X");
|
||||||
glm::quat q;
|
q.y = getFloatAttribute(element, "Y");
|
||||||
q.x = getFloatAttribute(element, "X");
|
q.z = getFloatAttribute(element, "Z");
|
||||||
q.y = getFloatAttribute(element, "Y");
|
q.w = getFloatAttribute(element, "W");
|
||||||
q.z = getFloatAttribute(element, "Z");
|
memcpy(outData, reinterpret_cast<char*>(&q), getTypeStride(typeName));
|
||||||
q.w = getFloatAttribute(element, "W");
|
} else if (typeName == "float") {
|
||||||
memcpy(outData, reinterpret_cast<char*>(&q), getTypeStride(typeName));
|
|
||||||
}
|
|
||||||
} else if (dataType == XSValue::DataType::dt_string) {
|
|
||||||
char* str = XMLString::transcode(element->getTextContent());
|
|
||||||
std::string standardString(str);
|
|
||||||
new (outData) std::string(str);
|
|
||||||
XMLString::release(&str);
|
|
||||||
//memcpy(outData, reinterpret_cast<char*>(&standardString), getTypeStride(typeName));
|
|
||||||
} else {
|
|
||||||
XSValue::Status status;
|
XSValue::Status status;
|
||||||
XSValue* val = XSValue::getActualValue(element->getTextContent(), dataType, status);
|
XSValue* val = XSValue::getActualValue(element->getTextContent(), xercesc::XSValue::DataType::dt_float, status);
|
||||||
memcpy(outData, reinterpret_cast<char*>(&val->fData.fValue), getTypeStride(typeName));
|
memcpy(outData, reinterpret_cast<char*>(&val->fData.fValue.f_float), getTypeStride(typeName));
|
||||||
|
} else if (typeName == "double") {
|
||||||
|
XSValue::Status status;
|
||||||
|
XSValue* val = XSValue::getActualValue(element->getTextContent(), xercesc::XSValue::DataType::dt_double, status);
|
||||||
|
memcpy(outData, reinterpret_cast<char*>(&val->fData.fValue.f_double), getTypeStride(typeName));
|
||||||
|
} else if (typeName == "bool") {
|
||||||
|
XSValue::Status status;
|
||||||
|
XSValue* val = XSValue::getActualValue(element->getTextContent(), xercesc::XSValue::DataType::dt_boolean, status);
|
||||||
|
memcpy(outData, reinterpret_cast<char*>(&val->fData.fValue.f_bool), getTypeStride(typeName));
|
||||||
|
} else {
|
||||||
|
XSValue::DataType dataType = XSValue::getDataType(XSTR(typeName.c_str()));
|
||||||
|
if (dataType == XSValue::DataType::dt_string) {
|
||||||
|
char* str = XMLString::transcode(element->getTextContent());
|
||||||
|
std::string standardString(str);
|
||||||
|
new (outData) std::string(str);
|
||||||
|
XMLString::release(&str);
|
||||||
|
//memcpy(outData, reinterpret_cast<char*>(&standardString), getTypeStride(typeName));
|
||||||
|
} else {
|
||||||
|
//XSValue::Status status;
|
||||||
|
//XSValue* val = XSValue::getActualValue(element->getTextContent(), dataType, status);
|
||||||
|
//memcpy(outData, reinterpret_cast<char*>(&val->fData.fValue), getTypeStride(typeName));
|
||||||
|
LOG_WARNING("Unknown native data type: %s", typeName.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
#include "Core/InputManager.h"
|
#include "Core/InputManager.h"
|
||||||
|
|
||||||
|
std::vector<unsigned int> InputManager::GLFWCharCallbackQueue;
|
||||||
|
std::vector<std::pair<double, double>> InputManager::GLFWScrollCallbackQueue;
|
||||||
|
|
||||||
void InputManager::Initialize()
|
void InputManager::Initialize()
|
||||||
{
|
{
|
||||||
// TODO: Gamepad
|
// TODO: Gamepad
|
||||||
//m_LastGamepadAxisState = std::array<GamepadAxisState, XUSER_MAX_COUNT>();
|
//m_LastGamepadAxisState = std::array<GamepadAxisState, XUSER_MAX_COUNT>();
|
||||||
//m_LastGamepadButtonState = std::array<GamepadButtonState, XUSER_MAX_COUNT>();
|
//m_LastGamepadButtonState = std::array<GamepadButtonState, XUSER_MAX_COUNT>();
|
||||||
|
glfwSetCharCallback(m_GLFWWindow, &InputManager::GLFWCharCallback);
|
||||||
|
glfwSetScrollCallback(m_GLFWWindow, &InputManager::GLFWScrollCallback);
|
||||||
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &InputManager::OnLockMouse);
|
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &InputManager::OnLockMouse);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &InputManager::OnUnlockMouse);
|
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &InputManager::OnUnlockMouse);
|
||||||
@@ -36,6 +41,15 @@ void InputManager::Update(double dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keyboard text input
|
||||||
|
for (unsigned int& c : GLFWCharCallbackQueue) {
|
||||||
|
Events::KeyboardChar e;
|
||||||
|
e.Timestamp = glfwGetTime();
|
||||||
|
e.Char = c;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
GLFWCharCallbackQueue.clear();
|
||||||
|
|
||||||
// Mouse buttons
|
// Mouse buttons
|
||||||
for (int i = 0; i <= GLFW_MOUSE_BUTTON_LAST; ++i) {
|
for (int i = 0; i <= GLFW_MOUSE_BUTTON_LAST; ++i) {
|
||||||
m_CurrentMouseState[i] = glfwGetMouseButton(m_GLFWWindow, i);
|
m_CurrentMouseState[i] = glfwGetMouseButton(m_GLFWWindow, i);
|
||||||
@@ -73,6 +87,14 @@ void InputManager::Update(double dt)
|
|||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mouse scroll
|
||||||
|
for (auto& pair : GLFWScrollCallbackQueue) {
|
||||||
|
Events::MouseScroll e;
|
||||||
|
std::tie(e.DeltaX, e.DeltaY) = pair;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
GLFWScrollCallbackQueue.clear();
|
||||||
|
|
||||||
// // Lock mouse while holding LMB
|
// // Lock mouse while holding LMB
|
||||||
// if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT])
|
// if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT])
|
||||||
// {
|
// {
|
||||||
@@ -196,6 +218,17 @@ void InputManager::PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputManager::GLFWCharCallback(GLFWwindow* window, unsigned int c)
|
||||||
|
{
|
||||||
|
GLFWCharCallbackQueue.push_back(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InputManager::GLFWScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
||||||
|
{
|
||||||
|
GLFWScrollCallbackQueue.push_back(std::make_pair(xoffset, yoffset));
|
||||||
|
}
|
||||||
|
|
||||||
bool InputManager::OnLockMouse(const Events::LockMouse &event)
|
bool InputManager::OnLockMouse(const Events::LockMouse &event)
|
||||||
{
|
{
|
||||||
m_MouseLocked = true;
|
m_MouseLocked = true;
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ Resource* ResourceManager::Load(std::string resourceType, std::string resourceNa
|
|||||||
LOG_WARNING("Hot-loading resource \"%s\"", resourceName.c_str());
|
LOG_WARNING("Hot-loading resource \"%s\"", resourceName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateResource(resourceType, resourceName, parent);
|
return CreateResource(resourceType, resourceName, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource* ResourceManager::CreateResource(std::string resourceType, std::string resourceName, Resource* parent)
|
Resource* ResourceManager::CreateResource(std::string resourceType, std::string resourceName, Resource* parent)
|
||||||
@@ -112,10 +112,16 @@ Resource* ResourceManager::CreateResource(std::string resourceType, std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call the factory function
|
// Call the factory function
|
||||||
Resource* resource = facIt->second(resourceName);
|
Resource* resource;
|
||||||
// Store IDs
|
try {
|
||||||
resource->TypeID = GetTypeID(resourceType);
|
resource = facIt->second(resourceName);
|
||||||
resource->ResourceID = GetNewResourceID(resource->TypeID);
|
// Store IDs
|
||||||
|
resource->TypeID = GetTypeID(resourceType);
|
||||||
|
resource->ResourceID = GetNewResourceID(resource->TypeID);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
resource = nullptr;
|
||||||
|
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": %s", resourceName.c_str(), resourceType.c_str(), e.what());
|
||||||
|
}
|
||||||
// Cache
|
// Cache
|
||||||
m_ResourceCache[std::make_pair(resourceType, resourceName)] = resource;
|
m_ResourceCache[std::make_pair(resourceType, resourceName)] = resource;
|
||||||
m_ResourceFromName[resourceName] = resource;
|
m_ResourceFromName[resourceName] = resource;
|
||||||
|
|||||||
@@ -11,12 +11,43 @@ EntityID World::CreateEntity(EntityID parent /*= 0*/)
|
|||||||
{
|
{
|
||||||
EntityID newEntity = generateEntityID();
|
EntityID newEntity = generateEntityID();
|
||||||
m_EntityParents[newEntity] = parent;
|
m_EntityParents[newEntity] = parent;
|
||||||
if (parent != 0) {
|
m_EntityChildren.insert(std::make_pair(parent, newEntity));
|
||||||
m_EntityChildren.insert(std::make_pair(parent, newEntity));
|
|
||||||
}
|
|
||||||
return newEntity;
|
return newEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void World::DeleteEntity(EntityID entity)
|
||||||
|
{
|
||||||
|
// Delete components
|
||||||
|
for (auto& pair : m_ComponentPools) {
|
||||||
|
auto& pool = pair.second;
|
||||||
|
if (pool->KnowsEntity(entity)) {
|
||||||
|
auto& c = pool->GetByEntity(entity);
|
||||||
|
pool->Delete(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through children
|
||||||
|
std::vector<EntityID> childrenToDelete;
|
||||||
|
auto children = m_EntityChildren.equal_range(entity);
|
||||||
|
for (auto it = children.first; it != children.second; ++it) {
|
||||||
|
childrenToDelete.push_back(it->second);
|
||||||
|
}
|
||||||
|
for (auto& child : childrenToDelete) {
|
||||||
|
DeleteEntity(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityID parent = m_EntityParents.at(entity);
|
||||||
|
m_EntityParents.erase(entity);
|
||||||
|
auto parentChildren = m_EntityChildren.equal_range(parent);
|
||||||
|
for (auto it = parentChildren.first; it != parentChildren.second; ++it) {
|
||||||
|
if (it->second == entity) {
|
||||||
|
m_EntityChildren.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void World::RegisterComponent(ComponentInfo& ci)
|
void World::RegisterComponent(ComponentInfo& ci)
|
||||||
{
|
{
|
||||||
m_ComponentPools[ci.Name] = new ComponentPool(ci);
|
m_ComponentPools[ci.Name] = new ComponentPool(ci);
|
||||||
@@ -35,12 +66,27 @@ ComponentWrapper World::AttachComponent(EntityID entity, std::string componentTy
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool World::HasComponent(EntityID entity, std::string componentType)
|
||||||
|
{
|
||||||
|
ComponentPool* pool = m_ComponentPools.at(componentType);
|
||||||
|
return pool->KnowsEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
ComponentWrapper World::GetComponent(EntityID entity, std::string componentType)
|
ComponentWrapper World::GetComponent(EntityID entity, std::string componentType)
|
||||||
{
|
{
|
||||||
ComponentPool* pool = m_ComponentPools.at(componentType);
|
ComponentPool* pool = m_ComponentPools.at(componentType);
|
||||||
return pool->GetByEntity(entity);
|
return pool->GetByEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void World::DeleteComponent(EntityID entity, std::string componentType)
|
||||||
|
{
|
||||||
|
ComponentPool* pool = m_ComponentPools.at(componentType);
|
||||||
|
ComponentWrapper c = pool->GetByEntity(entity);
|
||||||
|
return pool->Delete(c);
|
||||||
|
}
|
||||||
|
|
||||||
const ComponentPool* World::GetComponents(std::string componentType)
|
const ComponentPool* World::GetComponents(std::string componentType)
|
||||||
{
|
{
|
||||||
auto it = m_ComponentPools.find(componentType);
|
auto it = m_ComponentPools.find(componentType);
|
||||||
|
|||||||
@@ -0,0 +1,252 @@
|
|||||||
|
#include "Editor/EditorSystem.h"
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#include <imgui/imgui_internal.h>
|
||||||
|
|
||||||
|
EditorSystem::EditorSystem(EventBroker* eventBroker)
|
||||||
|
: ImpureSystem(eventBroker)
|
||||||
|
{
|
||||||
|
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
|
m_Enabled = config->Get<bool>("Debug.EditorEnabled", false);
|
||||||
|
m_Visible = m_Enabled;
|
||||||
|
|
||||||
|
if (!m_Enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EPicking, &EditorSystem::OnPicking);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorSystem::Update(World* world, double dt)
|
||||||
|
{
|
||||||
|
if (!m_Enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Widget == 0) {
|
||||||
|
m_Widget = world->CreateEntity();
|
||||||
|
world->AttachComponent(m_Widget, "Transform");
|
||||||
|
auto& model = world->AttachComponent(m_Widget, "Model");
|
||||||
|
model["Resource"] = "Models/TranslationWidget.obj";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Selection != m_LastSelection) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& widgetModel = world->GetComponent(m_Widget, "Model");
|
||||||
|
widgetModel["Visible"] = m_Visible;
|
||||||
|
if (m_Selection != 0) {
|
||||||
|
if (world->HasComponent(m_Selection, "Transform")) {
|
||||||
|
glm::vec3 pos = RenderQueueFactory::AbsolutePosition(world, m_Selection);
|
||||||
|
auto widgetTransform = world->GetComponent(m_Widget, "Transform");
|
||||||
|
widgetTransform["Position"] = pos;
|
||||||
|
} else {
|
||||||
|
m_Selection = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_Visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawUI(world, dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool EditorSystem::OnInputCommand(const Events::InputCommand& e)
|
||||||
|
{
|
||||||
|
if (e.Command == "ToggleEditor" && e.Value > 0) {
|
||||||
|
m_Visible = !m_Visible;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorSystem::OnMousePress(const Events::MousePress& e)
|
||||||
|
{
|
||||||
|
if (e.Button == GLFW_MOUSE_BUTTON_RIGHT) {
|
||||||
|
m_PickingQueue.push_back(glm::vec2((int)e.X, (int)e.Y));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorSystem::OnPicking(const Events::Picking& e)
|
||||||
|
{
|
||||||
|
for (auto& pos : m_PickingQueue) {
|
||||||
|
auto result = e.Pick(pos);
|
||||||
|
LOG_INFO("Selected %i", result.Entity);
|
||||||
|
m_Selection = result.Entity;
|
||||||
|
}
|
||||||
|
m_PickingQueue.clear();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
void EditorSystem::drawUI(World* world, double dt)
|
||||||
|
{
|
||||||
|
ImGui::ShowTestWindow();
|
||||||
|
//ImGui::ShowStyleEditor();
|
||||||
|
|
||||||
|
if (ImGui::BeginMainMenuBar()) {
|
||||||
|
if (ImGui::BeginMenu("File")) {
|
||||||
|
|
||||||
|
if (ImGui::MenuItem("New")) { }
|
||||||
|
if (ImGui::MenuItem("Open", "Ctrl+O")) { }
|
||||||
|
if (ImGui::MenuItem("Save", "Ctrl+S")) { }
|
||||||
|
if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S")) { }
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::MenuItem("Close Editor", "F1")) { }
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Move")) {
|
||||||
|
auto& model = world->GetComponent(m_Widget, "Model");
|
||||||
|
model["Resource"] = "Models/TranslationWidget.obj";
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Rotate")) {
|
||||||
|
auto& model = world->GetComponent(m_Widget, "Model");
|
||||||
|
model["Resource"] = "Models/RotationWidget.obj";
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Scale")) {
|
||||||
|
auto& model = world->GetComponent(m_Widget, "Model");
|
||||||
|
model["Resource"] = "Models/ScaleWidget.obj";
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndMainMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Begin("Components")) {
|
||||||
|
if (m_Selection != 0) {
|
||||||
|
auto& pools = world->GetComponentPools();
|
||||||
|
|
||||||
|
std::vector<const char*> componentTypes;
|
||||||
|
for (auto& pair : pools) {
|
||||||
|
// Only add components the entity doesn't already have
|
||||||
|
if (!pair.second->KnowsEntity(m_Selection)) {
|
||||||
|
componentTypes.push_back(pair.first.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int item = -1;
|
||||||
|
ImGui::PushItemWidth(ImGui::GetWindowContentRegionWidth() - 5.f);
|
||||||
|
if (ImGui::Combo("", &item, componentTypes.data(), componentTypes.size())) {
|
||||||
|
if (item != -1) {
|
||||||
|
std::string chosenType = std::string(componentTypes.at(item));
|
||||||
|
world->AttachComponent(m_Selection, chosenType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
for (auto& pair : pools) {
|
||||||
|
const std::string& componentType = pair.first;
|
||||||
|
auto pool = pair.second;
|
||||||
|
if (!pool->KnowsEntity(m_Selection)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto& ci = pool->ComponentInfo();
|
||||||
|
|
||||||
|
bool deletePressed = createDeleteButton(componentType);
|
||||||
|
if (deletePressed) {
|
||||||
|
world->DeleteComponent(m_Selection, componentType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader(componentType.c_str())) {
|
||||||
|
if (!ci.Meta.Annotation.empty()) {
|
||||||
|
ImGui::Text(ci.Meta.Annotation.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& component = world->GetComponent(m_Selection, componentType);
|
||||||
|
for (auto& pair : ci.FieldTypes) {
|
||||||
|
const std::string& field = pair.first;
|
||||||
|
const std::string& type = pair.second;
|
||||||
|
|
||||||
|
if (type == "Vector") {
|
||||||
|
auto& val = component.Property<glm::vec3>(field);
|
||||||
|
if (field == "Scale") {
|
||||||
|
ImGui::DragFloat3(field.c_str(), glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits<float>::max());
|
||||||
|
} else if (field == "Orientation") {
|
||||||
|
glm::vec3 tempVal = glm::fmod(val, glm::vec3(glm::two_pi<float>()));
|
||||||
|
if (ImGui::SliderFloat3(field.c_str(), glm::value_ptr(tempVal), 0.f, glm::two_pi<float>())) {
|
||||||
|
val = tempVal;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::DragFloat3(field.c_str(), glm::value_ptr(val), 0.1f, std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
|
||||||
|
}
|
||||||
|
} else if (type == "Color") {
|
||||||
|
auto& val = component.Property<glm::vec4>(field);
|
||||||
|
ImGui::ColorEdit4(field.c_str(), glm::value_ptr(val), true);
|
||||||
|
} else if (type == "string") {
|
||||||
|
std::string& val = component.Property<std::string>(field);
|
||||||
|
char tempString[1024];
|
||||||
|
memcpy(tempString, val.c_str(), std::min(val.length() + 1, sizeof(tempString)));
|
||||||
|
if (ImGui::InputText(field.c_str(), tempString, sizeof(tempString))) {
|
||||||
|
val = std::string(tempString);
|
||||||
|
LOG_DEBUG("%s::%s changed!", componentType.c_str(), field.c_str());
|
||||||
|
}
|
||||||
|
} else if (type == "double") {
|
||||||
|
float tempVal = static_cast<float>(component.Property<double>(field));
|
||||||
|
if (ImGui::InputFloat(field.c_str(), &tempVal, 0.01f, 1.f)) {
|
||||||
|
component.SetProperty(field, static_cast<double>(tempVal));
|
||||||
|
}
|
||||||
|
} else if (type == "bool") {
|
||||||
|
auto& val = component.Property<bool>(field);
|
||||||
|
ImGui::Checkbox(field.c_str(), &val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
if (ImGui::Begin("Entitites")) {
|
||||||
|
auto entityChildren = world->GetEntityChildren();
|
||||||
|
std::function<void(EntityID)> recurse = [&](EntityID parent) {
|
||||||
|
auto range = entityChildren.equal_range(parent);
|
||||||
|
for (auto it = range.first; it != range.second; it++) {
|
||||||
|
ImGui::SetNextTreeNodeOpened(true, ImGuiSetCond_Once);
|
||||||
|
if (ImGui::TreeNode((std::string("#") + std::to_string(it->second)).c_str())) {
|
||||||
|
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0)) {
|
||||||
|
m_Selection = it->second;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Add")) {
|
||||||
|
EntityID entity = world->CreateEntity(it->second);
|
||||||
|
world->AttachComponent(entity, "Transform");
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Delete")) {
|
||||||
|
world->DeleteEntity(it->second);
|
||||||
|
}
|
||||||
|
recurse(it->second);
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recurse(0);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorSystem::createDeleteButton(std::string componentType)
|
||||||
|
{
|
||||||
|
float width = ImGui::GetContentRegionAvailWidth();
|
||||||
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
auto pos = ImGui::GetCursorScreenPos() + ImVec2(width - 14.f, 1);
|
||||||
|
ImRect bb = ImRect(pos, pos + ImVec2(14.f, 14.f));
|
||||||
|
std::string idString = "#DELETE";
|
||||||
|
idString += componentType;
|
||||||
|
ImGuiID id = window->GetID(idString.c_str());
|
||||||
|
bool hovered;
|
||||||
|
bool held;
|
||||||
|
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held);
|
||||||
|
//ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton);
|
||||||
|
ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||||
|
window->DrawList->AddCircleFilled(bb.GetCenter(), 7.f, col, 16);
|
||||||
|
return pressed;
|
||||||
|
}
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
#include "Rendering/ImGuiRenderPass.h"
|
||||||
|
|
||||||
|
ImGuiRenderPass::ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker)
|
||||||
|
: m_Renderer(renderer)
|
||||||
|
, m_EventBroker(eventBroker)
|
||||||
|
{
|
||||||
|
g_Window = renderer->Window();
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||||
|
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
|
||||||
|
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
|
||||||
|
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
|
||||||
|
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
|
||||||
|
io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP;
|
||||||
|
io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN;
|
||||||
|
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
|
||||||
|
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
|
||||||
|
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
|
||||||
|
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
|
||||||
|
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
|
||||||
|
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
|
||||||
|
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
|
||||||
|
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
|
||||||
|
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
|
||||||
|
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
|
||||||
|
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
|
||||||
|
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
|
||||||
|
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.Alpha = 1.f;
|
||||||
|
style.WindowPadding = ImVec2(8.f, 7.f);
|
||||||
|
style.WindowRounding = 4.f;
|
||||||
|
style.ChildWindowRounding = 0.f;
|
||||||
|
style.FramePadding = ImVec2(4.f, 2.f);
|
||||||
|
style.FrameRounding = 2.f;
|
||||||
|
style.ItemSpacing = ImVec2(6.f, 2.f);
|
||||||
|
style.ItemInnerSpacing = ImVec2(3.f, 4.f);
|
||||||
|
style.IndentSpacing = 16.f;
|
||||||
|
style.ScrollbarSize = 12;
|
||||||
|
style.ScrollbarRounding = 2.f;
|
||||||
|
style.GrabMinSize = 13.f;
|
||||||
|
style.GrabRounding = 3.f;
|
||||||
|
|
||||||
|
createDeviceObjects();
|
||||||
|
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &ImGuiRenderPass::OnMousePress);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &ImGuiRenderPass::OnMouseRelease);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &ImGuiRenderPass::OnMouseMove);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EMouseScroll, &ImGuiRenderPass::OnMouseScroll);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &ImGuiRenderPass::OnKeyDown);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &ImGuiRenderPass::OnKeyUp);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyboardChar, &ImGuiRenderPass::OnKeyboardChar);
|
||||||
|
|
||||||
|
// Prime the first frame
|
||||||
|
newFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiRenderPass::Update(double dt)
|
||||||
|
{
|
||||||
|
g_DeltaTime = dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiRenderPass::Draw()
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui::Render();
|
||||||
|
|
||||||
|
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||||
|
|
||||||
|
// Backup GL state
|
||||||
|
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
||||||
|
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
|
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||||
|
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
|
||||||
|
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||||
|
GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src);
|
||||||
|
GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst);
|
||||||
|
GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb);
|
||||||
|
GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha);
|
||||||
|
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||||
|
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
||||||
|
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
|
||||||
|
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||||
|
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendEquation(GL_FUNC_ADD);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
// Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
|
||||||
|
float fb_height = io.DisplaySize.y * io.DisplayFramebufferScale.y;
|
||||||
|
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
|
||||||
|
|
||||||
|
// Setup viewport, orthographic projection matrix
|
||||||
|
glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y);
|
||||||
|
const float ortho_projection[4][4] =
|
||||||
|
{
|
||||||
|
{ 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, -1.0f, 0.0f },
|
||||||
|
{ -1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
};
|
||||||
|
glUseProgram(g_ShaderHandle);
|
||||||
|
glUniform1i(g_AttribLocationTex, 0);
|
||||||
|
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||||
|
glBindVertexArray(g_VaoHandle);
|
||||||
|
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++) {
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
const ImDrawIdx* idx_buffer_offset = 0;
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.size() * sizeof(ImDrawVert), (GLvoid*)&cmd_list->VtxBuffer.front(), GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx), (GLvoid*)&cmd_list->IdxBuffer.front(), GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) {
|
||||||
|
if (pcmd->UserCallback) {
|
||||||
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
|
||||||
|
glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
|
||||||
|
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
||||||
|
}
|
||||||
|
idx_buffer_offset += pcmd->ElemCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore modified GL state
|
||||||
|
glUseProgram(last_program);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
|
||||||
|
glBindVertexArray(last_vertex_array);
|
||||||
|
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
||||||
|
glBlendFunc(last_blend_src, last_blend_dst);
|
||||||
|
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
|
||||||
|
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
||||||
|
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
||||||
|
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
||||||
|
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
||||||
|
|
||||||
|
// Start next frame
|
||||||
|
newFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::OnMousePress(const Events::MousePress& e)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.MouseDown[e.Button] = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::OnMouseRelease(const Events::MouseRelease& e)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.MouseDown[e.Button] = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::OnMouseMove(const Events::MouseMove& e)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.MousePos.x = e.X;
|
||||||
|
io.MousePos.y = e.Y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::OnMouseScroll(const Events::MouseScroll& e)
|
||||||
|
{
|
||||||
|
g_MouseWheel += (float)e.DeltaY;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::OnKeyDown(const Events::KeyDown& e)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.KeysDown[e.KeyCode] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::OnKeyUp(const Events::KeyUp& e)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.KeysDown[e.KeyCode] = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::OnKeyboardChar(const Events::KeyboardChar& e)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
if (e.Char > 0 && e.Char < 0x10000) {
|
||||||
|
io.AddInputCharacter((unsigned short)e.Char);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::createDeviceObjects()
|
||||||
|
{
|
||||||
|
// Backup GL state
|
||||||
|
GLint last_texture, last_array_buffer, last_vertex_array;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
|
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||||
|
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||||
|
|
||||||
|
const GLchar *vertex_shader =
|
||||||
|
"#version 330\n"
|
||||||
|
"uniform mat4 ProjMtx;\n"
|
||||||
|
"in vec2 Position;\n"
|
||||||
|
"in vec2 UV;\n"
|
||||||
|
"in vec4 Color;\n"
|
||||||
|
"out vec2 Frag_UV;\n"
|
||||||
|
"out vec4 Frag_Color;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" Frag_UV = UV;\n"
|
||||||
|
" Frag_Color = Color;\n"
|
||||||
|
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
const GLchar* fragment_shader =
|
||||||
|
"#version 330\n"
|
||||||
|
"uniform sampler2D Texture;\n"
|
||||||
|
"in vec2 Frag_UV;\n"
|
||||||
|
"in vec4 Frag_Color;\n"
|
||||||
|
"out vec4 Out_Color;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
g_ShaderHandle = glCreateProgram();
|
||||||
|
g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(g_VertHandle, 1, &vertex_shader, 0);
|
||||||
|
glShaderSource(g_FragHandle, 1, &fragment_shader, 0);
|
||||||
|
glCompileShader(g_VertHandle);
|
||||||
|
glCompileShader(g_FragHandle);
|
||||||
|
glAttachShader(g_ShaderHandle, g_VertHandle);
|
||||||
|
glAttachShader(g_ShaderHandle, g_FragHandle);
|
||||||
|
glLinkProgram(g_ShaderHandle);
|
||||||
|
|
||||||
|
g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
|
||||||
|
g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
|
||||||
|
g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
|
||||||
|
g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
|
||||||
|
g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
|
||||||
|
|
||||||
|
glGenBuffers(1, &g_VboHandle);
|
||||||
|
glGenBuffers(1, &g_ElementsHandle);
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &g_VaoHandle);
|
||||||
|
glBindVertexArray(g_VaoHandle);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
|
||||||
|
glEnableVertexAttribArray(g_AttribLocationPosition);
|
||||||
|
glEnableVertexAttribArray(g_AttribLocationUV);
|
||||||
|
glEnableVertexAttribArray(g_AttribLocationColor);
|
||||||
|
|
||||||
|
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
|
||||||
|
glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
|
||||||
|
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
|
||||||
|
glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
|
||||||
|
#undef OFFSETOF
|
||||||
|
|
||||||
|
createFontsTexture();
|
||||||
|
|
||||||
|
// Restore modified GL state
|
||||||
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||||
|
glBindVertexArray(last_vertex_array);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiRenderPass::createFontsTexture()
|
||||||
|
{
|
||||||
|
// Build texture atlas
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
io.Fonts->AddFontFromFileTTF("Fonts/DroidSans.ttf", 13.f);
|
||||||
|
//io.Fonts->AddFontFromFileTTF("Fonts/ProggyClean.ttf", 13.f);
|
||||||
|
//io.Fonts->AddFontFromFileTTF("Fonts/ProggyTiny.ttf", 10.f);
|
||||||
|
//io.Fonts->AddFontFromFileTTF("Fonts/Karla-Regular.ttf", 15.0f);
|
||||||
|
|
||||||
|
unsigned char* pixels;
|
||||||
|
int width, height;
|
||||||
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader.
|
||||||
|
|
||||||
|
// Upload texture to graphics system
|
||||||
|
GLint last_texture;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
|
glGenTextures(1, &g_FontTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, g_FontTexture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
|
// Store our identifier
|
||||||
|
io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
|
||||||
|
|
||||||
|
// Restore state
|
||||||
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiRenderPass::newFrame()
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
// Setup display size (every frame to accommodate for window resizing)
|
||||||
|
int w, h;
|
||||||
|
int display_w, display_h;
|
||||||
|
glfwGetWindowSize(g_Window, &w, &h);
|
||||||
|
glfwGetFramebufferSize(g_Window, &display_w, &display_h);
|
||||||
|
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||||
|
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
||||||
|
|
||||||
|
io.DeltaTime = g_DeltaTime;
|
||||||
|
|
||||||
|
io.KeyCtrl = glfwGetKey(g_Window, GLFW_KEY_LEFT_CONTROL) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_CONTROL);
|
||||||
|
io.KeyShift = glfwGetKey(g_Window, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_SHIFT);
|
||||||
|
io.KeyAlt = glfwGetKey(g_Window, GLFW_KEY_LEFT_ALT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_ALT);
|
||||||
|
|
||||||
|
io.MouseWheel = g_MouseWheel;
|
||||||
|
g_MouseWheel = 0;
|
||||||
|
|
||||||
|
m_EventBroker->Process<ImGuiRenderPass>();
|
||||||
|
|
||||||
|
ImGui::NewFrame();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -93,12 +93,15 @@ void PickingPass::Draw(RenderQueueCollection& rq)
|
|||||||
GLERROR("PickingPass Error");
|
GLERROR("PickingPass Error");
|
||||||
|
|
||||||
//Publish pick event every frame with the pick data that can be picked by the event
|
//Publish pick event every frame with the pick data that can be picked by the event
|
||||||
|
int fbWidth;
|
||||||
|
int fbHeight;
|
||||||
|
glfwGetFramebufferSize(m_Renderer->Window(), &fbWidth, &fbHeight);
|
||||||
Events::Picking pickEvent = Events::Picking(
|
Events::Picking pickEvent = Events::Picking(
|
||||||
&m_PickingBuffer,
|
&m_PickingBuffer,
|
||||||
&m_DepthBuffer,
|
&m_DepthBuffer,
|
||||||
m_Renderer->Camera()->ProjectionMatrix(),
|
m_Renderer->Camera()->ProjectionMatrix(),
|
||||||
m_Renderer->Camera()->ViewMatrix(),
|
m_Renderer->Camera()->ViewMatrix(),
|
||||||
m_Renderer->Resolution(),
|
Rectangle(fbWidth, fbHeight),
|
||||||
&m_PickingColorsToEntity);
|
&m_PickingColorsToEntity);
|
||||||
|
|
||||||
m_EventBroker->Publish(pickEvent);
|
m_EventBroker->Publish(pickEvent);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ RawModel::RawModel(std::string fileName)
|
|||||||
if (scene == nullptr) {
|
if (scene == nullptr) {
|
||||||
LOG_ERROR("Failed to load model \"%s\"", fileName.c_str());
|
LOG_ERROR("Failed to load model \"%s\"", fileName.c_str());
|
||||||
LOG_ERROR("Assimp error: %s", importer.GetErrorString());
|
LOG_ERROR("Assimp error: %s", importer.GetErrorString());
|
||||||
return;
|
throw std::runtime_error("Failed to open model file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto m = scene->mRootNode->mTransformation;
|
auto m = scene->mRootNode->mTransformation;
|
||||||
|
|||||||
@@ -23,15 +23,19 @@ glm::mat4 RenderQueueFactory::ModelMatrix(World* world, EntityID entity)
|
|||||||
return modelMatrix;
|
return modelMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity)
|
glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity)
|
||||||
{
|
{
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
position += (glm::vec3)transform["Position"];
|
EntityID parent = world->GetParent(entity);
|
||||||
entity = world->GetParent(entity);
|
if (parent != 0) {
|
||||||
|
position += AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"];
|
||||||
|
} else {
|
||||||
|
position += (glm::vec3)transform["Position"];
|
||||||
|
}
|
||||||
|
entity = parent;
|
||||||
} while (entity != 0);
|
} while (entity != 0);
|
||||||
|
|
||||||
return position;
|
return position;
|
||||||
@@ -52,15 +56,15 @@ glm::quat RenderQueueFactory::AbsoluteOrientation(World* world, EntityID entity)
|
|||||||
|
|
||||||
glm::vec3 RenderQueueFactory::AbsoluteScale(World* world, EntityID entity)
|
glm::vec3 RenderQueueFactory::AbsoluteScale(World* world, EntityID entity)
|
||||||
{
|
{
|
||||||
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
glm::vec3 scale(1.f);
|
||||||
glm::vec3 scale = (glm::vec3)transform["Scale"];
|
|
||||||
|
|
||||||
EntityID parent = world->GetParent(entity);
|
do {
|
||||||
if (parent != 0) {
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
return AbsoluteScale(world, parent) * scale;
|
scale *= (glm::vec3)transform["Scale"];
|
||||||
} else {
|
entity = world->GetParent(entity);
|
||||||
return scale;
|
} while (entity != 0);
|
||||||
}
|
|
||||||
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
|
void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
|
||||||
@@ -71,12 +75,19 @@ void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto& modelC : *models) {
|
for (auto& modelC : *models) {
|
||||||
|
bool visible = modelC["Visible"];
|
||||||
|
if (!visible) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
std::string resource = modelC["Resource"];
|
std::string resource = modelC["Resource"];
|
||||||
if (resource.empty()) {
|
if (resource.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glm::vec4 color = modelC["Color"];
|
glm::vec4 color = modelC["Color"];
|
||||||
Model* model = ResourceManager::Load<Model>(resource);
|
Model* model = ResourceManager::Load<Model>(resource);
|
||||||
|
if (model == nullptr) {
|
||||||
|
model = ResourceManager::Load<Model>("Models/Core/Error.obj");
|
||||||
|
}
|
||||||
|
|
||||||
for (auto texGroup : model->TextureGroups) {
|
for (auto texGroup : model->TextureGroups) {
|
||||||
ModelJob job;
|
ModelJob job;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ bool RenderState::Enable(GLenum GLEnable)
|
|||||||
{
|
{
|
||||||
if(glIsEnabled(GLEnable))
|
if(glIsEnabled(GLEnable))
|
||||||
{
|
{
|
||||||
LOG_WARNING("Trying to enable somthing that is already enabled.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_Enables.push_back(GLEnable);
|
m_Enables.push_back(GLEnable);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ void Renderer::Initialize()
|
|||||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||||
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
|
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
|
||||||
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");
|
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");
|
||||||
|
|
||||||
|
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::InitializeWindow()
|
void Renderer::InitializeWindow()
|
||||||
@@ -127,6 +129,7 @@ void Renderer::Update(double dt)
|
|||||||
{
|
{
|
||||||
m_EventBroker->Process<Renderer>();
|
m_EventBroker->Process<Renderer>();
|
||||||
InputUpdate(dt);
|
InputUpdate(dt);
|
||||||
|
m_ImGuiRenderPass->Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Draw(RenderQueueCollection& rq)
|
void Renderer::Draw(RenderQueueCollection& rq)
|
||||||
@@ -135,8 +138,13 @@ void Renderer::Draw(RenderQueueCollection& rq)
|
|||||||
//DrawScreenQuad(m_PickingPass->PickingTexture());
|
//DrawScreenQuad(m_PickingPass->PickingTexture());
|
||||||
//CullLights();
|
//CullLights();
|
||||||
|
|
||||||
|
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
m_DrawScenePass->Draw(rq);
|
m_DrawScenePass->Draw(rq);
|
||||||
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
|
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
|
||||||
|
m_ImGuiRenderPass->Draw();
|
||||||
glfwSwapBuffers(m_Window);
|
glfwSwapBuffers(m_Window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,10 @@ glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, float scr
|
|||||||
ScreenCoords::PixelData ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
ScreenCoords::PixelData ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
||||||
{
|
{
|
||||||
PickDataBuffer->Bind();
|
PickDataBuffer->Bind();
|
||||||
unsigned char pdata[2];
|
unsigned char pdata[3];
|
||||||
glReadPixels(x, y, 1, 1, GL_RG, GL_UNSIGNED_BYTE, &pdata);
|
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pdata);
|
||||||
PickDataBuffer->Unbind();
|
PickDataBuffer->Unbind();
|
||||||
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer);
|
||||||
float depthData;
|
float depthData;
|
||||||
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData);
|
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData);
|
||||||
|
|||||||
+3
-5
@@ -52,8 +52,7 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_SystemPipeline = new SystemPipeline(m_EventBroker);
|
m_SystemPipeline = new SystemPipeline(m_EventBroker);
|
||||||
m_SystemPipeline->AddSystem<RaptorCopterSystem>();
|
m_SystemPipeline->AddSystem<RaptorCopterSystem>();
|
||||||
m_SystemPipeline->AddSystem<PlayerSystem>();
|
m_SystemPipeline->AddSystem<PlayerSystem>();
|
||||||
|
m_SystemPipeline->AddSystem<EditorSystem>();
|
||||||
|
|
||||||
|
|
||||||
m_LastTime = glfwGetTime();
|
m_LastTime = glfwGetTime();
|
||||||
|
|
||||||
@@ -68,6 +67,8 @@ Game::~Game()
|
|||||||
|
|
||||||
void Game::Tick()
|
void Game::Tick()
|
||||||
{
|
{
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
double currentTime = glfwGetTime();
|
double currentTime = glfwGetTime();
|
||||||
double dt = currentTime - m_LastTime;
|
double dt = currentTime - m_LastTime;
|
||||||
m_LastTime = currentTime;
|
m_LastTime = currentTime;
|
||||||
@@ -79,7 +80,6 @@ void Game::Tick()
|
|||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_InputProxy->Update(dt);
|
m_InputProxy->Update(dt);
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_EventBroker->Clear();
|
|
||||||
m_InputProxy->Process();
|
m_InputProxy->Process();
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
|
|
||||||
@@ -94,8 +94,6 @@ void Game::Tick()
|
|||||||
GLERROR("Game::Tick m_Renderer->Draw");
|
GLERROR("Game::Tick m_Renderer->Draw");
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_EventBroker->Clear();
|
m_EventBroker->Clear();
|
||||||
|
|
||||||
glfwPollEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "PlayerSystem.h"
|
#include "PlayerSystem.h"
|
||||||
|
|
||||||
|
void PlayerSystem::UpdateComponent(World * world, ComponentWrapper & player, double dt)
|
||||||
void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt)
|
|
||||||
{
|
{
|
||||||
if (input.Forward) {
|
if (input.Forward) {
|
||||||
m_Direction.z = -1;
|
m_Direction.z = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user