Merge remote-tracking branch 'origin/master' into Rendering

# Conflicts:
#	src/Engine/Editor/EditorSystem.cpp
#	src/Engine/Rendering/PickingPass.cpp
#	src/Game/Game.cpp
This commit is contained in:
viktorljung
2015-12-17 11:17:58 +01:00
20 changed files with 540 additions and 199 deletions
+3
View File
@@ -31,6 +31,8 @@ public:
const ComponentPool* GetComponents(std::string componentType);
// Get entity parent
EntityID GetParent(EntityID entity);
// Change the parent of an entity
void SetParent(EntityID entity, EntityID parent);
// Get all component pools
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
// Get the entity children map
@@ -40,6 +42,7 @@ private:
EntityID m_CurrentEntityID = 1;
std::unordered_map<EntityID, EntityID> m_EntityParents;
// TODO: This should be a more effective structure
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
+37 -1
View File
@@ -2,34 +2,70 @@
#include <glm/gtx/common.hpp>
#include "../Core/System.h"
#include "../Core/EMousePress.h"
#include "../Core/EMouseRelease.h"
#include "../Core/EMouseMove.h"
#include "../Core/ConfigFile.h"
#include "../Input/EInputCommand.h"
#include "../Rendering/IRenderer.h"
#include "../Rendering/EPicking.h"
#include "../Rendering/RenderSystem.h"
class EditorSystem : public ImpureSystem
{
public:
EditorSystem(EventBroker* eventBroker);
EditorSystem(EventBroker* eventBroker, IRenderer* renderer);
virtual void Update(World* world, double dt) override;
private:
IRenderer* m_Renderer;
World* m_World = nullptr;
bool m_Enabled;
bool m_Visible;
std::vector<glm::vec2> m_PickingQueue;
enum class WidgetMode
{
None,
Translate,
Rotate,
Scale
} m_WidgetMode = WidgetMode::None;
enum class WidgetSpace
{
Local,
Global
} m_WidgetSpace = WidgetSpace::Global;
EntityID m_Widget = 0;
EntityID m_WidgetX = 0;
EntityID m_WidgetY = 0;
EntityID m_WidgetZ = 0;
EntityID m_WidgetOrigin = 0;
glm::vec3 m_WidgetCurrentAxis;
float m_WidgetPickingDepth = 0.f;
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::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e);
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e);
EventRelay<EditorSystem, Events::MouseMove> m_EMouseMove;
bool OnMouseMove(const Events::MouseMove& e);
EventRelay<EditorSystem, Events::Picking> m_EPicking;
bool OnPicking(const Events::Picking& e);
void updateWidget();
void setWidgetMode(WidgetMode newMode);
void setWidgetSpace(WidgetSpace space);
void drawUI(World* world, double dt);
bool createDeleteButton(std::string componentType);
void changeParent(EntityID entity, EntityID newParent);
};
+3
View File
@@ -34,6 +34,8 @@ public:
EntityID Entity;
//World position of the "pick"
glm::vec3 Position;
// Depth
float Depth;
};
PickData Pick(glm::vec2 screenCoord) const
@@ -43,6 +45,7 @@ public:
// Invert screen y coordinate
screenCoord.y = Resolution.Height - screenCoord.y;
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer);
pickData.Depth = data.Depth;
auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1]));
if (it != PickingColorsToEntity->end()) {
@@ -1,6 +1,7 @@
#include <imgui/imgui.h>
#include "../OpenGL.h"
#include "IRenderer.h"
#include "RenderState.h"
#include "../Core/EventBroker.h"
#include "../Core/EMousePress.h"
#include "../Core/EMouseRelease.h"
@@ -10,6 +11,22 @@
#include "../Core/EKeyUp.h"
#include "../Core/EKeyboardChar.h"
class ImGuiRenderState : public RenderState
{
public:
ImGuiRenderState()
: RenderState()
{
BindFramebuffer(0);
Enable(GL_BLEND);
BlendEquation(GL_FUNC_ADD);
BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Disable(GL_CULL_FACE);
Disable(GL_DEPTH_TEST);
Enable(GL_SCISSOR_TEST);
}
};
class ImGuiRenderPass
{
public:
+11 -7
View File
@@ -1,6 +1,7 @@
#ifndef RenderState_h__
#define RenderState_h__
#include <functional>
#include "../Common.h"
#include "../OpenGL.h"
#include "../GLM.h"
@@ -8,16 +9,19 @@
class RenderState
{
public:
RenderState();
RenderState() = default;
~RenderState();
bool Enable(GLenum GLEnable);
bool CullFace(GLenum GlFaceToCull);
bool Enable(GLenum cap);
bool Disable(GLenum cap);
bool CullFace(GLenum mode);
bool ClearColor(glm::vec4 color);
bool Clear(GLbitfield mask);
bool BindBuffer(GLint buffer);
bool BindFramebuffer(GLint framebuffer);
bool BlendEquation(GLenum mode);
bool BlendFunc(GLenum sfactor, GLenum dfactor);
private:
std::vector<GLenum> m_Enables;
float m_preClearColor[4];
int m_preBuffer;
std::vector<std::function<void(void)>> m_ResetFunctions;
};
#endif
+1
View File
@@ -1,6 +1,7 @@
[Debug]
LogLevel=1
LoadMap=
EditorEnabled=false
[Video]
Fullscreen=false
+5
View File
@@ -14,3 +14,8 @@ R=Reload
Space=Jump
LeftControl=Crouch
LeftShift=Sprint
F1=ToggleEditor
1=EditorToolMove
2=EditorToolRotate
3=EditorToolScale
X=EditorToggleTransformSpace
+1 -1
View File
@@ -1,5 +1,5 @@
<c:Transform>
<Position X="0" Y="0" Z="0"/>
<Orientation X="0" Y="0" Z="0" W="0"/>
<Orientation X="0" Y="0" Z="0"/>
<Scale X="1" Y="1" Z="1"/>
</c:Transform>
+21 -2
View File
@@ -2,7 +2,10 @@
<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>
<c:Transform>
<Position X="0" Y="0" Z="0"/>
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
@@ -19,12 +22,28 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="1" Z="0"/>
<Position X="1" Y="1" Z="0"/>
<Orientation X="0" Y="0.78539" Z="0"/>
</c:Transform>
<c:Model>
<Resource>An error</Resource>
</c:Model>
</Components>
<Children>
<Entity>
<Components>
<c:Transform>
<Position X="2" Y="0" Z="0"/>
<Orientation X="0" Y="0.78539" Z="0"/>
</c:Transform>
<c:Model>
<Resource>An error</Resource>
</c:Model>
</Components>
<Children>
</Children>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
+2 -2
View File
@@ -431,12 +431,12 @@ float EntityXMLFile::getFloatAttribute(const xercesc::DOMElement* element, const
{
using namespace xercesc;
XSValue::Status status;
XSValue* val = XSValue::getActualValue(element->getAttribute(XSTR(attribute)), xercesc::XSValue::DataType::dt_float, status);
XSValue* val = XSValue::getActualValue(element->getAttribute(XSTR(attribute)), xercesc::XSValue::DataType::dt_double, status);
if (val == nullptr) {
LOG_ERROR("Element \"%s\" doesn't have an \"%s\" attribute!", XSTR(element->getTagName()), attribute);
return 0.f;
} else {
return val->fData.fValue.f_float;
return static_cast<float>(val->fData.fValue.f_double);
}
}
+16
View File
@@ -99,6 +99,22 @@ EntityID World::GetParent(EntityID entity)
return m_EntityParents.at(entity);
}
void World::SetParent(EntityID entity, EntityID parent)
{
EntityID lastParent = m_EntityParents.at(entity);
auto parentChildren = m_EntityChildren.equal_range(lastParent);
for (auto it = parentChildren.first; it != parentChildren.second; it++) {
if (it->second == entity) {
m_EntityChildren.erase(it);
break;
}
}
m_EntityParents[entity] = parent;
m_EntityChildren.insert(std::make_pair(parent, entity));
}
EntityID World::generateEntityID()
{
// TODO: Make EntityID generation smarter
+319 -38
View File
@@ -2,8 +2,9 @@
#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui/imgui_internal.h>
EditorSystem::EditorSystem(EventBroker* eventBroker)
EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer)
: ImpureSystem(eventBroker)
, m_Renderer(renderer)
{
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
m_Enabled = config->Get<bool>("Debug.EditorEnabled", false);
@@ -15,51 +16,52 @@ EditorSystem::EditorSystem(EventBroker* eventBroker)
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorSystem::OnMouseRelease);
EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &EditorSystem::OnMouseMove);
EVENT_SUBSCRIBE_MEMBER(m_EPicking, &EditorSystem::OnPicking);
}
void EditorSystem::Update(World* world, double dt)
{
m_World = world;
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 = RenderSystem::AbsolutePosition(world, m_Selection);
auto widgetTransform = world->GetComponent(m_Widget, "Transform");
widgetTransform["Position"] = pos;
} else {
m_Selection = 0;
}
}
if (!m_Visible) {
return;
}
updateWidget();
drawUI(world, dt);
}
bool EditorSystem::OnInputCommand(const Events::InputCommand& e)
{
if (e.Command == "ToggleEditor" && e.Value > 0) {
m_Visible = !m_Visible;
}
if (e.Command == "EditorToolMove" && e.Value > 0) {
setWidgetMode(WidgetMode::Translate);
}
if (e.Command == "EditorToolRotate" && e.Value > 0) {
setWidgetMode(WidgetMode::Rotate);
}
if (e.Command == "EditorToolScale" && e.Value > 0) {
setWidgetMode(WidgetMode::Scale);
}
if (e.Command == "EditorToggleTransformSpace" && e.Value > 0) {
if (m_WidgetSpace == WidgetSpace::Global) {
setWidgetSpace(WidgetSpace::Local);
} else if (m_WidgetSpace == WidgetSpace::Local) {
setWidgetSpace(WidgetSpace::Global);
}
}
return true;
}
@@ -71,17 +73,232 @@ bool EditorSystem::OnMousePress(const Events::MousePress& e)
return true;
}
bool EditorSystem::OnMouseMove(const Events::MouseMove& e)
{
if (m_Widget == 0) {
return false;
}
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
glm::vec3 widgetOrientation = widgetTransform["Orientation"];
glm::quat totalOrientation = m_Renderer->Camera()->Orientation() * glm::inverse(glm::quat(widgetOrientation));
int width;
int height;
glfwGetFramebufferSize(m_Renderer->Window(), &width, &height);
Rectangle res(width, height);
glm::vec2 delta2(res.Width / 2.f + e.DeltaX, res.Height / 2.f + -e.DeltaY);
glm::vec3 deltaWorld = ScreenCoords::ToWorldPos(
delta2,
m_WidgetPickingDepth,
res,
m_Renderer->Camera()->ProjectionMatrix(),
glm::toMat4(glm::inverse(totalOrientation))
);
glm::vec3 origin = ScreenCoords::ToWorldPos(
glm::vec2(res.Width / 2.f, res.Height / 2.f),
m_WidgetPickingDepth,
res,
m_Renderer->Camera()->ProjectionMatrix(),
glm::toMat4(glm::inverse(totalOrientation))
);
deltaWorld = deltaWorld - origin;
glm::vec3 movement = deltaWorld * m_WidgetCurrentAxis;
if (glm::length2(m_WidgetCurrentAxis) > 0.f) {
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
if (m_WidgetMode == WidgetMode::Translate) {
if (m_WidgetSpace == WidgetSpace::Global) {
EntityID parent = m_World->GetParent(m_Selection);
glm::quat inverseParentOrientation;
if (parent != 0) {
inverseParentOrientation = glm::inverse(RenderQueueFactory::AbsoluteOrientation(m_World, parent));
}
(glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Position"] += inverseParentOrientation * movement;
} else if (m_WidgetSpace == WidgetSpace::Local) {
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
(glm::vec3&)selectionTransform["Position"] += glm::quat((glm::vec3)selectionTransform["Orientation"]) * movement;
}
} else if (m_WidgetMode == WidgetMode::Rotate) {
glm::vec3 finalMovement;
finalMovement.x = -deltaWorld.y * m_WidgetCurrentAxis.x;
finalMovement.y = deltaWorld.x * m_WidgetCurrentAxis.y;
finalMovement.z = deltaWorld.y * m_WidgetCurrentAxis.z;
if (m_WidgetSpace == WidgetSpace::Global) {
EntityID parent = m_World->GetParent(m_Selection);
glm::quat parentOrientation;
if (parent != 0) {
parentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, parent);
}
glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"];
//glm::quat currentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection);
glm::quat currentOrientation = parentOrientation * glm::quat(selectionOrientation);
glm::quat deltaOrientation(finalMovement);
selectionOrientation = glm::eulerAngles(glm::inverse(parentOrientation) * (deltaOrientation * currentOrientation));
} else if (m_WidgetSpace == WidgetSpace::Local) {
glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"];
glm::quat currentOrientation(selectionOrientation);
glm::quat deltaOrientation(finalMovement);
selectionOrientation = glm::eulerAngles(currentOrientation * deltaOrientation);
}
} else if (m_WidgetMode == WidgetMode::Scale) {
glm::vec3& scaleX = m_World->GetComponent(m_WidgetX, "Transform")["Scale"];
glm::vec3& scaleY = m_World->GetComponent(m_WidgetY, "Transform")["Scale"];
glm::vec3& scaleZ = m_World->GetComponent(m_WidgetZ, "Transform")["Scale"];
if (m_WidgetCurrentAxis.x > 0) {
scaleX.x += movement.x;
}
if (m_WidgetCurrentAxis.y > 0) {
scaleY.y += movement.y;
}
if (m_WidgetCurrentAxis.z > 0) {
scaleZ.z += movement.z;
}
if (m_WidgetCurrentAxis.x > 0 && m_WidgetCurrentAxis.y > 0 && m_WidgetCurrentAxis.z > 0) {
float max = glm::max(scaleX.x, glm::max(scaleY.y, scaleZ.z));
(glm::vec3&)m_World->GetComponent(m_WidgetOrigin, "Transform")["Scale"] = glm::vec3(max);
}
(glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Scale"] += movement;
}
}
return true;
}
bool EditorSystem::OnMouseRelease(const Events::MouseRelease& e)
{
if (glm::length2(m_WidgetCurrentAxis) > 0.f) {
m_WidgetCurrentAxis = glm::vec3(0.f);
//setWidgetMode(m_WidgetMode);
}
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;
EntityID entity = result.Entity;
if (glm::length2(m_WidgetCurrentAxis) > 0.f) {
} else {
LOG_INFO("Selected %i", entity);
if (entity != 0) {
EntityID parent = m_World->GetParent(entity);
if (parent == m_Widget) {
m_WidgetCurrentAxis = glm::vec3(
(entity == m_WidgetX) || (entity == m_WidgetOrigin),
(entity == m_WidgetY) || (entity == m_WidgetOrigin),
(entity == m_WidgetZ) || (entity == m_WidgetOrigin)
);
m_WidgetPickingDepth = result.Depth;
//auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
//auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
//widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"];
} else {
ImGui::SetActiveID(0, nullptr);
m_Selection = entity;
setWidgetMode(m_WidgetMode);
}
} else {
m_Selection = 0;
}
}
}
m_PickingQueue.clear();
return true;
};
void EditorSystem::updateWidget()
{
if (m_Widget == 0) {
m_Widget = m_World->CreateEntity();
m_World->AttachComponent(m_Widget, "Transform");
m_WidgetX = m_World->CreateEntity(m_Widget);
m_World->AttachComponent(m_WidgetX, "Transform");
m_World->AttachComponent(m_WidgetX, "Model");
m_WidgetY = m_World->CreateEntity(m_Widget);
m_World->AttachComponent(m_WidgetY, "Transform");
m_World->AttachComponent(m_WidgetY, "Model");
m_WidgetZ = m_World->CreateEntity(m_Widget);
m_World->AttachComponent(m_WidgetZ, "Transform");
m_World->AttachComponent(m_WidgetZ, "Model");
m_WidgetOrigin = m_World->CreateEntity(m_Widget);
m_World->AttachComponent(m_WidgetOrigin, "Transform");
m_World->AttachComponent(m_WidgetOrigin, "Model");
setWidgetMode(WidgetMode::Translate);
}
if (m_Selection != 0) {
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
glm::vec3 selectionPosition = RenderQueueFactory::AbsolutePosition(m_World, m_Selection);
widgetTransform["Position"] = selectionPosition;
if (m_WidgetSpace == WidgetSpace::Local) {
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
}
}
}
void EditorSystem::setWidgetMode(WidgetMode newMode)
{
if (m_Widget == 0) {
return;
}
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
widgetTransform["Orientation"] = glm::vec3(0.f);
m_World->GetComponent(m_WidgetX, "Transform")["Scale"] = glm::vec3(1.f);
m_World->GetComponent(m_WidgetY, "Transform")["Scale"] = glm::vec3(1.f);
m_World->GetComponent(m_WidgetZ, "Transform")["Scale"] = glm::vec3(1.f);
m_World->GetComponent(m_WidgetOrigin, "Transform")["Scale"] = glm::vec3(1.f);
if (newMode == WidgetMode::Translate) {
m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/TranslationWidgetX.obj";
m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/TranslationWidgetY.obj";
m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/TranslationWidgetZ.obj";
m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = false;
if (m_Selection != 0) {
if (m_WidgetSpace == WidgetSpace::Local) {
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
}
}
} else if (newMode == WidgetMode::Scale) {
m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/ScaleWidgetX.obj";
m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/ScaleWidgetY.obj";
m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/ScaleWidgetZ.obj";
m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = true;
m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj";
if (m_Selection != 0) {
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
widgetTransform["Orientation"] = (glm::vec3)selectionTransform["Orientation"];
}
} else if (newMode == WidgetMode::Rotate) {
m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj";
m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/RotationWidgetY.obj";
m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/RotationWidgetZ.obj";
m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = false;
if (m_Selection != 0) {
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
if (m_WidgetSpace == WidgetSpace::Local) {
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
}
}
}
m_WidgetMode = newMode;
}
void EditorSystem::setWidgetSpace(WidgetSpace space)
{
m_WidgetSpace = space;
setWidgetMode(m_WidgetMode);
}
void EditorSystem::drawUI(World* world, double dt)
{
ImGui::ShowTestWindow();
@@ -102,24 +319,32 @@ void EditorSystem::drawUI(World* world, double dt)
ImGui::SameLine();
if (ImGui::Button("Move")) {
auto& model = world->GetComponent(m_Widget, "Model");
model["Resource"] = "Models/TranslationWidget.obj";
setWidgetMode(WidgetMode::Translate);
}
ImGui::SameLine();
if (ImGui::Button("Rotate")) {
auto& model = world->GetComponent(m_Widget, "Model");
model["Resource"] = "Models/RotationWidget.obj";
setWidgetMode(WidgetMode::Rotate);
}
ImGui::SameLine();
if (ImGui::Button("Scale")) {
auto& model = world->GetComponent(m_Widget, "Model");
model["Resource"] = "Models/ScaleWidget.obj";
setWidgetMode(WidgetMode::Scale);
}
ImGui::SameLine();
if (m_WidgetSpace == WidgetSpace::Global) {
if (ImGui::Button("(Global)")) {
setWidgetSpace(WidgetSpace::Local);
}
} else if (m_WidgetSpace == WidgetSpace::Local) {
if (ImGui::Button("(Local)")) {
setWidgetSpace(WidgetSpace::Global);
}
}
ImGui::EndMainMenuBar();
}
if (ImGui::Begin("Components")) {
std::string title = std::string("Components #") + std::to_string(m_Selection) + std::string("###Components");
if (ImGui::Begin(title.c_str())) {
if (m_Selection != 0) {
auto& pools = world->GetComponentPools();
@@ -205,16 +430,49 @@ void EditorSystem::drawUI(World* world, double dt)
ImGui::End();
if (ImGui::Begin("Entitites")) {
static EntityID draggingEntity = 0;
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)) {
ImVec2 pos = ImGui::GetCursorScreenPos();
float width = ImGui::GetContentRegionAvailWidth();
ImRect bb(pos + ImVec2(20, 0), pos + ImVec2(width, 13));
auto window = ImGui::GetCurrentWindow();
if (m_Selection == it->second) {
const ImU32 col = window->Color(ImGuiCol_HeaderActive);
window->DrawList->AddRectFilled(bb.Min, bb.Max, col);
}
ImGuiID id = window->GetID((std::string("#SelectButton") + std::to_string(it->second)).c_str());
bool hovered = false;
bool held = false;
if (ImGui::ButtonBehavior(bb, id, &hovered, &held)) {
m_Selection = it->second;
}
ImGui::SameLine();
if (held) {
ImVec2 entityDragDelta = ImGui::GetMouseDragDelta(0);
if (std::abs(entityDragDelta.x) > 0 && std::abs(entityDragDelta.y) > 0) {
if (draggingEntity == 0) {
draggingEntity = it->second;
LOG_DEBUG("Started drag of entity %i", draggingEntity);
}
ImGui::SetNextWindowPos(ImGui::GetIO().MousePos + ImVec2(20, 0));
ImGui::Begin("Change parent", nullptr, ImVec2(0, 0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings);
ImGui::Text("#%i", draggingEntity);
ImGui::End();
}
}
ImGui::SetNextTreeNodeOpened(true, ImGuiSetCond_Once);
if (ImGui::TreeNode((std::string("#") + std::to_string(it->second)).c_str())) {
if (draggingEntity != 0 && ImGui::IsItemHoveredRect() && ImGui::IsMouseReleased(0)) {
LOG_DEBUG("Changed parent of %i to %i", draggingEntity, it->second);
changeParent(draggingEntity, it->second);
draggingEntity = 0;
}
if (ImGui::BeginPopupContextItem("item context menu")) {
if (ImGui::Button("Add")) {
EntityID entity = world->CreateEntity(it->second);
world->AttachComponent(entity, "Transform");
@@ -222,6 +480,12 @@ void EditorSystem::drawUI(World* world, double dt)
ImGui::SameLine();
if (ImGui::Button("Delete")) {
world->DeleteEntity(it->second);
ImGui::CloseCurrentPopup();
if (m_Selection == it->second) {
m_Selection = 0;
}
}
ImGui::EndPopup();
}
recurse(it->second);
ImGui::TreePop();
@@ -250,3 +514,20 @@ bool EditorSystem::createDeleteButton(std::string componentType)
window->DrawList->AddCircleFilled(bb.GetCenter(), 7.f, col, 16);
return pressed;
}
void EditorSystem::changeParent(EntityID entity, EntityID newParent)
{
if (entity == newParent) {
return;
}
// An entity can't be a child to one of its own children
auto children = m_World->GetEntityChildren().equal_range(entity);
for (auto it = children.first; it != children.second; it++) {
if (it->second == newParent) {
return;
}
}
m_World->SetParent(entity, newParent);
}
+1 -1
View File
@@ -4,7 +4,7 @@
DrawScenePassState::DrawScenePassState()
{
GLERROR("---");
BindBuffer(0);
BindFramebuffer(0);
GLERROR("---");
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
+2 -37
View File
@@ -69,29 +69,8 @@ void ImGuiRenderPass::Draw()
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);
// Set up render state
ImGuiRenderState state;
glActiveTexture(GL_TEXTURE0);
// Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
@@ -134,20 +113,6 @@ void ImGuiRenderPass::Draw()
}
}
// 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();
}
+16 -14
View File
@@ -48,26 +48,31 @@ void PickingPass::Draw(RenderQueueCollection& rq)
m_PickingColorsToEntity.clear();
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
int r = 1;
int r = 0;
int g = 0;
//TODO: Render: Add code for more jobs than modeljobs.
GLuint ShaderHandle = m_PickingProgram->GetHandle();
m_PickingProgram->Bind();
std::map<EntityID, glm::vec2> entityColors;
for (auto &job : rq.Forward) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if (modelJob) {
//---------------
//TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame.
//---------------
int pickColor[2] = { r, g };
for (auto i : m_PickingColorsToEntity) {
if (modelJob->Entity == i.second) {
pickColor[0] = i.first.x;
pickColor[1] = i.first.y;
r -= 1;
auto color = entityColors.find(modelJob->Entity);
if (color != entityColors.end()) {
pickColor[0] = color->second[0];
pickColor[1] = color->second[1];
} else {
entityColors[modelJob->Entity] = glm::vec2(pickColor[0], pickColor[1]);
if (r + 10 > 255) {
r = 0;
g += 1;
} else {
r += 1;
}
}
m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity;
@@ -78,11 +83,6 @@ void PickingPass::Draw(RenderQueueCollection& rq)
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex);
r += 1;
if (r > 255) {
r = 0;
g += 1;
}
}
}
m_PickingBuffer.Unbind();
@@ -101,6 +101,8 @@ void PickingPass::Draw(RenderQueueCollection& rq)
&m_PickingColorsToEntity);*/
//m_EventBroker->Publish(pickEvent);
delete state;
}
void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const
+1 -1
View File
@@ -4,7 +4,7 @@
PickingPassState::PickingPassState(GLuint frameBuffer)
{
GLERROR("---2");
BindBuffer(frameBuffer);
BindFramebuffer(frameBuffer);
GLERROR("---3");
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
+63 -74
View File
@@ -1,110 +1,99 @@
#include "Rendering/RenderState.h"
RenderState::RenderState()
{
}
bool RenderState::Enable(GLenum GLEnable)
{
if(glIsEnabled(GLEnable))
bool RenderState::Enable(GLenum cap)
{
if (glIsEnabled(cap)) {
return false;
}
m_Enables.push_back(GLEnable);
glEnable(GLEnable);
if (GLERROR("RenderState::Enable"))
{
return false;
}
return true;
m_ResetFunctions.push_back(std::bind(glDisable, cap));
glEnable(cap);
return !GLERROR("RenderState::Enable");
}
bool RenderState::CullFace(GLenum GLCullFace)
bool RenderState::Disable(GLenum cap)
{
if(!glIsEnabled(GL_CULL_FACE))
if (!glIsEnabled(cap)) {
return false;
}
m_ResetFunctions.push_back(std::bind(glEnable, cap));
glDisable(cap);
return !GLERROR("RenderState::Disable");
}
bool RenderState::CullFace(GLenum mode)
{
if (!glIsEnabled(GL_CULL_FACE)) {
LOG_ERROR("Setting GL_CULL_FACE without enabling it.");
return false;
}
GLint a;
glGetIntegerv(GL_CULL_FACE_MODE, &a);
if(a != GL_BACK)
{
//LOG_INFO("Setting Cullface to back, unessesary since this is already default.");
glCullFace(GLCullFace);
}
if (GLERROR("RenderState::CullFace"))
{
return false;
}
return true;
GLint original;
glGetIntegerv(GL_CULL_FACE_MODE, &original);
m_ResetFunctions.push_back(std::bind(glCullFace, original));
glCullFace(mode);
return !GLERROR("RenderState::CullFace");
}
bool RenderState::ClearColor(glm::vec4 color)
{
glGetFloatv(GL_COLOR_CLEAR_VALUE, &m_preClearColor[0]);
GLfloat original[4];
glGetFloatv(GL_COLOR_CLEAR_VALUE, &original[0]);
m_ResetFunctions.push_back(std::bind(glClearColor, original[0], original[1], original[2], original[3]));
glClearColor(color.r, color.g, color.b, color.a);
if (GLERROR("RenderState::ClearColor")) {
return false;
}
return true;
return !GLERROR("RenderState::ClearColor");
}
bool RenderState::Clear(GLbitfield mask)
{
glClear(mask);
if (GLERROR("RenderState::Clear")) {
return false;
}
return true;
return !GLERROR("RenderState::Clear");
}
bool RenderState::BindBuffer(GLint buffer)
bool RenderState::BindFramebuffer(GLint framebuffer)
{
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_preBuffer);
if (buffer == m_preBuffer)
{
return true;
GLint originalRead;
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &originalRead);
GLint originalDraw;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &originalDraw);
m_ResetFunctions.push_back([originalRead, originalDraw]() {
glBindFramebuffer(GL_READ_FRAMEBUFFER, originalRead);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, originalDraw);
});
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
return !GLERROR("RenderState::BindBuffer");
}
glBindFramebuffer(GL_FRAMEBUFFER, buffer);
if (GLERROR("RenderState::BindBuffer"))
bool RenderState::BlendEquation(GLenum mode)
{
printf("BufferID: %i\npreBufferID: %i\n", buffer, m_preBuffer);
return false;
GLint originalRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &originalRGB);
GLint originalAlpha;
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &originalAlpha);
m_ResetFunctions.push_back(std::bind(glBlendEquationSeparate, originalRGB, originalAlpha));
glBlendEquation(mode);
return !GLERROR("RenderState::BlendEquation");
}
return true;
bool RenderState::BlendFunc(GLenum sfactor, GLenum dfactor)
{
GLint originalSrcRGB;
glGetIntegerv(GL_BLEND_SRC_RGB, &originalSrcRGB);
GLint originalSrcAlpha;
glGetIntegerv(GL_BLEND_SRC_ALPHA, &originalSrcAlpha);
GLint originalDestRGB;
glGetIntegerv(GL_BLEND_DST_RGB, &originalDestRGB);
GLint originalDestAlpha;
glGetIntegerv(GL_BLEND_DST_ALPHA, &originalDestAlpha);
m_ResetFunctions.push_back(std::bind(glBlendFuncSeparate, originalSrcRGB, originalSrcAlpha, originalDestRGB, originalDestAlpha));
glBlendFunc(sfactor, dfactor);
return !GLERROR("RenderState::BlendFunc");
}
RenderState::~RenderState()
{
GLERROR("RenderState::~RenderState Pre");
GLint n_buffer = -1;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &n_buffer);
//Set cullface to default
if (glIsEnabled(GL_CULL_FACE)) {
glCullFace(GL_BACK);
for (auto& f : m_ResetFunctions) {
f();
}
GLERROR("RenderState::~RenderState glCullFace");
//Set color to default
glClearColor(m_preClearColor[0], m_preClearColor[1], m_preClearColor[2], m_preClearColor[3]);
GLERROR("RenderState::~RenderState glClearColor");
//Disable Enables
for (auto i : m_Enables)
{
glDisable(i);
}
GLERROR("RenderState::~RenderState glDisable");
if(m_preBuffer != 0)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
m_Enables.clear();
GLERROR("RenderState::~RenderState glBindFramebuffer");
}
-2
View File
@@ -101,8 +101,6 @@ void Renderer::Draw(RenderQueueCollection& rq)
//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);
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
+8 -8
View File
@@ -14,12 +14,7 @@ Game::Game(int argc, char* argv[])
// Create the core event broker
m_EventBroker = new EventBroker();
// Create a world
m_World = new World();
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
if (!mapToLoad.empty()) {
ResourceManager::Load<EntityXMLFile>(mapToLoad)->PopulateWorld(m_World);
}
m_RenderQueueFactory = new RenderQueueFactory();
// Create the renderer
m_Renderer = new Renderer(m_EventBroker, m_World);
@@ -46,13 +41,18 @@ Game::Game(int argc, char* argv[])
m_FrameStack->Width = m_Renderer->Resolution().Width;
m_FrameStack->Height = m_Renderer->Resolution().Height;
// Create a world
m_World = new World();
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
if (!mapToLoad.empty()) {
ResourceManager::Load<EntityXMLFile>(mapToLoad)->PopulateWorld(m_World);
}
m_RenderQueues = new RenderQueueCollection();
// Create system pipeline
m_SystemPipeline = new SystemPipeline(m_EventBroker);
m_SystemPipeline->AddSystem<RaptorCopterSystem>();
m_SystemPipeline->AddSystem<PlayerSystem>();
m_SystemPipeline->AddSystem<EditorSystem>();
m_SystemPipeline->AddSystem<EditorSystem>(m_Renderer);
m_SystemPipeline->AddSystem<RenderSystem>(m_RenderQueues);
m_LastTime = glfwGetTime();
+2
View File
@@ -11,6 +11,8 @@ RMDIR "%DeployLocation%\Textures"
MKLINK "%DeployLocation%\Textures\" "assets\Textures\" /J
RMDIR "%DeployLocation%\Audio"
MKLINK "%DeployLocation%\Audio\" "assets\Audio\" /J
RMDIR "%DeployLocation%\Fonts"
MKLINK "%DeployLocation%\Fonts\" "assets\Fonts\" /J
ECHO Deploying resources to %DeployLocation%
:: Schemas