Improved architecute

further abstracting away the runtime
This commit is contained in:
Nigel Barink 2022-11-05 19:14:23 +01:00
parent 02e14aa8fa
commit 28c64b43ba
15 changed files with 436 additions and 435 deletions

View File

@ -0,0 +1,9 @@
#pragma once
struct EditorContext {
std::shared_ptr<Project> CurrentProject;
Scene MainScene;
EditorContext() = default;
EditorContext(EditorContext& other) = default;
~EditorContext() = default;
};

70
Editor/src/SceneRuntime.h Normal file
View File

@ -0,0 +1,70 @@
#pragma once
#include "../../YoggieEngine/src/BarinkEngine.h"
#include "../../YoggieEngine/src/AssetManager/ModelImporter.h"
#include "../../YoggieEngine/src/Graphics/Memory/Framebuffer.h"
#include "../../YoggieEngine/src/PerfCounter.cpp"
#include "../../YoggieEngine/src/Scene/Entity.h"
#include "Project.h"
class SceneRuntime : public ApplicationRuntime {
public:
SceneRuntime() = default;
void Start() override
{
CurrentProject = std::make_shared<Project>("Random");
framebuffer = new Framebuffer();
// Create a level and load it as the current level
auto importer = ModelImporter();
// Create a cube
Model = importer.Import("build/Debug/Models/Cube.obj");
cube = MainScene.AddEntity("cube");
auto& render3DComponent = cube.AddComponent<Render3DComponent>();
render3DComponent.mesh = *(Model->renderable->mesh);
cube.GetComponent<TransformComponent>().Position = glm::vec3(1.0f, 0.0f, 5.0f);
auto cube2 = MainScene.AddEntity("Cube1");
auto& rendercube2 = cube2.AddComponent<Render3DComponent>();
rendercube2.mesh = *(Model->renderable->mesh);
// create an ambient light source
auto AmbientLight = MainScene.AddEntity("AmbientLight");
auto light = AmbientLight.AddComponent<LightComponent>();
light.Color = glm::vec3(1.0f);
light.Strength = 1.0f;
Selected = (entt::entity)-1;
}
void Update() override
{
}
void FixedUpdate() override
{
}
void Stop() override
{
}
private:
std::shared_ptr<Project> CurrentProject = nullptr;
Scene MainScene;
Framebuffer* framebuffer;
SceneObject* Model;
Entity cube;
entt::entity Selected;
friend class Editor;
};

View File

@ -108,7 +108,7 @@ void SceneExplorer(entt::entity& selected, Scene& scene )
ImGui::End(); ImGui::End();
} }
void Viewport(Framebuffer& framebuffer, Scene& scene) { void Viewport(Framebuffer& framebuffer) {
unsigned int viewportWindowFlags = ImGuiWindowFlags_NoTitleBar unsigned int viewportWindowFlags = ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDecoration

View File

@ -17,7 +17,7 @@ void Inspector(entt::entity entity, Scene& scene);
void SceneExplorer(entt::entity& selected, Scene& scene); void SceneExplorer(entt::entity& selected, Scene& scene);
void Viewport(Framebuffer& framebuffer, Scene& scene); void Viewport(Framebuffer& framebuffer);
void Settings(); void Settings();

270
Editor/src/app.cpp Normal file
View File

@ -0,0 +1,270 @@
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <imgui.h>
#include <backends/imgui_impl_opengl3.h>
#include <backends/imgui_impl_glfw.h>
#include <imgui_internal.h>
#include <nfd.h>
#include "../../libs/guizmo/ImGuizmo.h"
#include "UI/Widgets.h"
#include "Project.h"
#include "SceneSerializer.h"
#include "EditorContext.h"
#include "SceneRuntime.h"
#include "../../YoggieEngine/src/BarinkEngine.h"
const unsigned int MS_PER_UPDATE = 2;
class Editor : public Application {
public:
Editor() : Application("Editor") {}
void Run() override
{
BarinkWindow mainWindow = BarinkWindow(1200, 700);
InputSystem = new InputManager();
renderer = new Renderer();
InputSystem->attach(&mainWindow);
InitImGui(mainWindow);
activeRuntime.Start();
double previous = glfwGetTime();
double lag = 0.0;
renderer->Prepare(activeRuntime.MainScene);
while (!mainWindow.WindowShouldClose())
{
double current = glfwGetTime();
double elapsed = current - previous;
previous = current;
lag += elapsed;
InputSystem->PollEvents();
while (lag >= MS_PER_UPDATE)
{
activeRuntime.Update();
lag -= MS_PER_UPDATE;
}
renderer->Render(activeRuntime.framebuffer, activeRuntime.MainScene);
ImGuiBegin();
RenderGUI();
ImGuiEnd();
mainWindow.SwapBuffers();
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
}
activeRuntime.Stop();
delete InputSystem;
delete renderer;
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void InitImGui(BarinkWindow& window )
{
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_::ImGuiConfigFlags_ViewportsEnable;
io.ConfigFlags |= ImGuiConfigFlags_::ImGuiConfigFlags_DockingEnable;
io.Fonts->AddFontFromFileTTF("build/Debug/Fonts/Roboto-Regular.ttf", 18);
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(window.windowptr(), true);
ImGui_ImplOpenGL3_Init("#version 440");
}
void ImGuiBegin() {
ImGui_ImplGlfw_NewFrame();
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();
ImGuizmo::SetOrthographic(true);
ImGuizmo::BeginFrame();
}
void ImGuiEnd() {
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
GLFWwindow* last_context = glfwGetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
glfwMakeContextCurrent(last_context);
}
}
void RenderGUI() {
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
// Show a menu bar
ImGui::BeginMainMenuBar();
if (ImGui::BeginMenu("Application")) {
if (ImGui::MenuItem("Load Project"))
{
nfdresult_t result = NFD_OpenDialog({ "yproj" }, NULL, &path);
switch (result) {
case(NFD_OKAY):
Project::LoadProject(path, activeRuntime.CurrentProject);
break;
case(NFD_CANCEL):
break;
case(NFD_ERROR):
std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
break;
}
}
if (ImGui::MenuItem("Save project as...")) {
nfdresult_t result = NFD_SaveDialog({ "yproj" }, NULL, &savePath);
switch (result) {
case(NFD_OKAY):
std::cout << "Save as: " << savePath << std::endl;
Project::SaveProject(savePath, *activeRuntime.CurrentProject.get());
break;
case(NFD_CANCEL):
break;
case(NFD_ERROR):
std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
break;
}
}
if (ImGui::MenuItem("Preferences"))
{
}
if (ImGui::MenuItem("Exit"))
{
// TODO: Exit application
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Scene")) {
if (ImGui::MenuItem("Save scene"))
{
nfdresult_t result = NFD_SaveDialog({ "yscene" }, NULL, &scenePath);
switch (result) {
case(NFD_OKAY):
SaveScene(scenePath, activeRuntime.MainScene);
break;
case(NFD_CANCEL):
break;
case(NFD_ERROR):
std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
break;
}
}
if (ImGui::MenuItem("Load scene"))
{
auto result = NFD_OpenDialog({ "yscene" }, NULL, &openScenePath);
switch (result) {
case (NFD_OKAY):
LoadScene(openScenePath, activeRuntime.MainScene);
break;
case(NFD_CANCEL):
break;
case(NFD_ERROR):
std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
break;
}
}
if (ImGui::MenuItem("Add Entity")) {
activeRuntime.MainScene.AddEntity("New Entity");
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
ImGui::Begin("ProjectInfo");
ImGui::Text("Project: %s", activeRuntime.CurrentProject.get()->GetName().c_str());
ImGui::Text("Directory: %s", activeRuntime.CurrentProject.get()->GetProjectDirectory().u8string().c_str());
ImGui::End();
//ShowStats();
Viewport(*activeRuntime.framebuffer);
SceneExplorer(activeRuntime.Selected, activeRuntime.MainScene);
Inspector(activeRuntime.Selected, activeRuntime.MainScene);
Settings();
AssetsFinder();
Console();
ImGui::ShowDemoWindow();
ImGui::ShowMetricsWindow();
}
private:
EditorContext context;
SceneRuntime activeRuntime ;
char* path = nullptr;
char* savePath = nullptr;
char* scenePath = nullptr;
char* openScenePath = nullptr;
};
int main (int argc , char* argv[]) {
Editor().Run();
}

View File

@ -1,242 +0,0 @@
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <imgui.h>
#include <imgui_internal.h>
#include <nfd.h>
#include "../../libs/guizmo/ImGuizmo.h"
#include "../../YoggieEngine/src/BarinkEngine.h"
#include "../../YoggieEngine/src/AssetManager/ModelImporter.h"
#include "../../YoggieEngine/src/Graphics/Memory/Framebuffer.h"
#include "../../YoggieEngine/src/PerfCounter.cpp"
#include "../../YoggieEngine/src/Scene/Entity.h"
#include "UI/Widgets.h"
#include "Project.h"
#include "SceneSerializer.h"
using namespace YoggieEngine;
/*
* Define globals
*/
struct EditorContext {
Project CurrentProject;
Scene MainScene;
EditorContext() = default;
EditorContext(EditorContext& other) = default;
~EditorContext() = default;
};
std::shared_ptr<Project> CurrentProject;
Scene MainScene;
Framebuffer* framebuffer;
SceneObject* Model;
Entity cube;
entt::entity Selected;
/*
* Runs once at startup
* - USe to initialize the game/sandbox/demo
*/
void Start() {
CurrentProject = std::make_shared<Project>("Random");
auto io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("build/Debug/Fonts/Roboto-Regular.ttf", 18);
framebuffer = new Framebuffer();
// Create a level and load it as the current level
auto importer = ModelImporter();
// Create a cube
Model = importer.Import("build/Debug/Models/Cube.obj");
cube = MainScene.AddEntity("cube");
auto& render3DComponent = cube.AddComponent<Render3DComponent>();
render3DComponent.mesh = *(Model->renderable->mesh);
cube.GetComponent<TransformComponent>().Position = glm::vec3(1.0f, 0.0f, 5.0f);
auto cube2 = MainScene.AddEntity("Cube1");
auto& rendercube2 = cube2.AddComponent<Render3DComponent>();
rendercube2.mesh = *(Model->renderable->mesh);
// create an ambient light source
auto AmbientLight = MainScene.AddEntity("AmbientLight");
auto light = AmbientLight.AddComponent<LightComponent>();
light.Color = glm::vec3(1.0f);
light.Strength = 1.0f;
Selected = (entt::entity) -1;
renderer.Prepare(MainScene);
}
char* path = nullptr;
char* savePath = nullptr;
char* scenePath = nullptr;
char* openScenePath = nullptr;
/*
* Runs every frame
* - Use to draw Immediate mode graphics (Not meant for HUD's )
*/
void ImmediateGraphicsDraw()
{ ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
// Show a menu bar
ImGui::BeginMainMenuBar();
if (ImGui::BeginMenu("Application")) {
if (ImGui::MenuItem("Load Project"))
{
nfdresult_t result = NFD_OpenDialog({ "yproj" }, NULL, &path);
switch (result) {
case(NFD_OKAY):
Project::LoadProject( path, CurrentProject);
break;
case(NFD_CANCEL):
break;
case(NFD_ERROR):
std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
break;
}
}
if (ImGui::MenuItem("Save project as...")) {
nfdresult_t result = NFD_SaveDialog({ "yproj" }, NULL, &savePath);
switch (result) {
case(NFD_OKAY):
std::cout << "Save as: " << savePath << std::endl;
Project::SaveProject(savePath, *CurrentProject.get());
break;
case(NFD_CANCEL):
break;
case(NFD_ERROR):
std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
break;
}
}
if (ImGui::MenuItem("Preferences"))
{
}
if (ImGui::MenuItem("Exit"))
{
// TODO: Exit application
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Scene")) {
if (ImGui::MenuItem("Save scene"))
{
nfdresult_t result= NFD_SaveDialog({"yscene"},NULL, &scenePath);
switch (result) {
case(NFD_OKAY):
SaveScene(scenePath, MainScene);
break;
case(NFD_CANCEL):
break;
case(NFD_ERROR):
std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
break;
}
}
if (ImGui::MenuItem("Load scene"))
{
auto result = NFD_OpenDialog({ "yscene" }, NULL, &openScenePath);
switch (result) {
case (NFD_OKAY):
LoadScene(openScenePath, MainScene);
break;
case(NFD_CANCEL):
break;
case(NFD_ERROR):
std::cout << "NFD_Error: " << NFD_GetError() << std::endl;
break;
}
}
if (ImGui::MenuItem("Add Entity")) {
MainScene.AddEntity("New entity");
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
ImGui::Begin("ProjectInfo");
ImGui::Text("Project: %s", CurrentProject.get()->GetName().c_str());
ImGui::Text("Directory: %s", CurrentProject.get()->GetProjectDirectory().u8string().c_str());
ImGui::End();
//ShowStats();
Viewport(*framebuffer, MainScene);
SceneExplorer(Selected, MainScene);
Inspector(Selected, MainScene );
Settings();
AssetsFinder();
Console();
ImGui::ShowDemoWindow();
ImGui::ShowMetricsWindow();
}
void Render()
{
renderer.Render( *framebuffer, MainScene);
}
/*
* Runs every frame
* - Meant for game logic ( non-physics related)
*/
void Update()
{
}
/*
* Runs every physics update
*/
void fixed_update()
{
}
/*
* Runs at the end of the program
* - Meant for cleanup
*/
void Stop()
{
delete framebuffer;
}

View File

@ -0,0 +1,18 @@
#include "Application.h"
namespace YoggieEngine {
Application::Application(const std::string& name )
: m_AppName(name)
{
EngineInstrumentation::PerfomanceSamplerInit();
}
void Application::Run() {
std::cout << "No run function implemented!";
}
}

View File

@ -0,0 +1,36 @@
#pragma once
#include "Input/InputManager.h"
#include "Graphics/Renderer.h"
#include <string>
#include <iostream>
#include <memory>
namespace YoggieEngine {
// forward declaration
class InputManager;
class Application {
public:
Application(const std::string& name);
virtual void Run();
protected:
std::string m_AppName;
Renderer* renderer = nullptr;
InputManager* InputSystem = nullptr;
friend class ApplicationRuntime;
};
class ApplicationRuntime {
public:
virtual void Start() = 0;
virtual void Update() = 0;
virtual void FixedUpdate() = 0;
virtual void Stop() = 0;
};
};

View File

@ -1,84 +1 @@
#include "BarinkEngine.h" #include "BarinkEngine.h"
using namespace YoggieEngine;
Renderer renderer;
const unsigned int MS_PER_UPDATE = 2;
int main(int argc, char* argv[]) {
// Setup performance sampler
EngineInstrumentation::PerfomanceSamplerInit();
// Startup services
BarinkWindow MainWindow = BarinkWindow(1200, 700);
renderer = Renderer();
InputSystem = InputManager();
InputSystem.attach(&MainWindow);
GUIManager GUISystem = GUIManager(&MainWindow);
glEnable(GL_DEPTH_TEST);
// First call to setup game
{
Start();
}
double previous = glfwGetTime();
double lag = 0.0;
// Runtime loop
while (!MainWindow.WindowShouldClose())
{
double current = glfwGetTime();
double elapsed = current - previous;
previous = current;
lag += elapsed;
//EngineInstrumentation::Update(); // Todo this does nothing right now and is therefor disabled
// Execute main logic
{
InputSystem.PollEvents();
}
{
while (lag >= MS_PER_UPDATE) {
Update();
lag -= MS_PER_UPDATE;
}
}
{
Render();
}
{
GUISystem.Render();
}
{
MainWindow.SwapBuffers();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
}
// Shutdown game
{
Stop();
}
// Shutdown Services
return 0;
}

View File

@ -1,21 +1,23 @@
#pragma once #pragma once
#include "glm/glm.hpp" #include <glad/glad.h>
#include "graphics/Primitives/Shader.h"
#include "Platform/Window.h"
#include "graphics/Primitives/Texture.h"
#include "graphics/Primitives/Camera.h"
#include "graphics/Renderable.h"
#include "Graphics/Renderer.h"
#include "Graphics/Primitives/Material.h"
#include "Input/InputManager.h"
#include "Graphics/Renderer.h"
#include "GUI/GUIManager.h"
#include "Scene/Scene.h"
using namespace YoggieEngine;
extern Renderer renderer;
extern void Start();
extern void Update(); #include "glm/glm.hpp"
extern void Render();
extern void ImmediateGraphicsDraw(); #include "Platform/Window.h"
extern void Stop();
#include "Graphics/Primitives/Shader.h"
#include "Graphics/Primitives/Texture.h"
#include "Graphics/Primitives/Camera.h"
#include "Graphics/Primitives/Material.h"
#include "Graphics/Renderer.h"
#include "spdlog/spdlog.h"
#include "EventSystem/EventEmitter.h"
#include "EventSystem/EventListener.h"
#include "Input/InputManager.h"
#include "Scene/Scene.h"
#include "Application.h"

View File

@ -1,65 +0,0 @@
#include "GUIManager.h"
#include "imgui.h"
#include "backends/imgui_impl_opengl3.h"
#include <backends/imgui_impl_glfw.h>
#include "../../libs/guizmo/ImGuizmo.h"
#include "../BarinkEngine.h"
namespace YoggieEngine {
GUIManager::GUIManager(BarinkWindow* window)
: currentwindow(window)
{
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_::ImGuiConfigFlags_ViewportsEnable;
io.ConfigFlags |= ImGuiConfigFlags_::ImGuiConfigFlags_DockingEnable;
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(currentwindow->windowptr(), true);
ImGui_ImplOpenGL3_Init("#version 440");
}
GUIManager::~GUIManager()
{
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void GUIManager::Render()
{
ImGui_ImplGlfw_NewFrame();
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();
ImGuizmo::SetOrthographic(true);
ImGuizmo::BeginFrame();
ImmediateGraphicsDraw();
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
GLFWwindow* last_context = glfwGetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
glfwMakeContextCurrent(last_context);
}
}
}

View File

@ -1,14 +0,0 @@
#pragma once
#include "../Platform/Window.h"
namespace YoggieEngine {
class GUIManager {
public:
GUIManager(BarinkWindow* window);
~GUIManager();
void Render();
private:
BarinkWindow* currentwindow;
};
}

View File

@ -10,7 +10,10 @@ float Angle = 0.0;
Camera cam = Camera(glm::vec3(12.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 90.0f); Camera cam = Camera(glm::vec3(12.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 90.0f);
glm::mat4 projection = glm::perspective(glm::radians(cam.Zoom), (800.0f / 600.0f), 0.001f, 100.0f); glm::mat4 projection = glm::perspective(glm::radians(cam.Zoom), (800.0f / 600.0f), 0.001f, 100.0f);
Renderer::Renderer(){} Renderer::Renderer(){
glEnable(GL_DEPTH_TEST);
}
Renderer::~Renderer(){} Renderer::~Renderer(){}
@ -88,10 +91,12 @@ void Renderer::Render(Scene& scene)
} }
void Renderer::Render(Framebuffer& framebuffer, Scene& scene) void Renderer::Render(Framebuffer* framebuffer, Scene& scene)
{ {
if (framebuffer == nullptr)
return;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.GetId()); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->GetId());
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

View File

@ -22,6 +22,6 @@ namespace YoggieEngine {
void Prepare(Scene& scene); void Prepare(Scene& scene);
void Render(Scene& scene ); void Render(Scene& scene );
void Render(Framebuffer& framebuffer, Scene& scene); void Render(Framebuffer* framebuffer, Scene& scene);
}; };
} }

View File

@ -1,11 +1,6 @@
#pragma once #pragma once
#include <vector> #include "../BarinkEngine.h"
#include <iostream>
#include "spdlog/spdlog.h"
#include "../EventSystem/EventEmitter.h"
#include "../EventSystem/EventListener.h"
#include "../Platform/Window.h"
namespace YoggieEngine { namespace YoggieEngine {