Improving the editor, ImGuizmo is now rendering guizmo's

- Added Guzimo's to the sceneview
- Added new menu to the menubar
- Improved multiple widgets (ImGui windows)
- Added a new RuntimeControl widget (ImGui window)
- New Screenshots
This commit is contained in:
Nigel Barink 2022-12-24 02:10:29 +01:00
parent ad79aa2865
commit 3fa5455b43
9 changed files with 289 additions and 98 deletions

View File

@ -16,6 +16,8 @@ includedirs{
-- I'd prefer if didn't need these.. -- I'd prefer if didn't need these..
-- We'll figure that out some time later -- We'll figure that out some time later
"../libs/physx/physx/include",
"../libs/physx/pxshared/include",
incfolder["lua"], incfolder["lua"],
incfolder["spdlog"], incfolder["spdlog"],
incfolder["glm"], incfolder["glm"],

View File

@ -5,7 +5,7 @@
class EditorWindow { class EditorWindow {
public: public:
EditorWindow(const std::string& name ) { ImGui::Begin(name.c_str()); } EditorWindow(const std::string& name, ImGuiWindowFlags_ flags = ImGuiWindowFlags_None ) { ImGui::Begin(name.c_str(), false ,flags); }

View File

@ -22,6 +22,7 @@ public:
ImGui_ImplGlfw_InitForOpenGL(window.GetGLFWHandle(), true); ImGui_ImplGlfw_InitForOpenGL(window.GetGLFWHandle(), true);
ImGui_ImplOpenGL3_Init("#version 450"); ImGui_ImplOpenGL3_Init("#version 450");
ImGuizmo::SetImGuiContext(ImGui::GetCurrentContext());
ImGuizmo::SetOrthographic(true); ImGuizmo::SetOrthographic(true);
} }

View File

@ -138,6 +138,33 @@ public:
} }
} }
void DebugMenu()
{
if (ImGui::BeginMenu("Debug")) {
ImGui::EndMenu();
}
}
void SelectMenu() {
if (ImGui::BeginMenu("Select")) {
ImGui::EndMenu();
}
}
void WindowMenu() {
if (ImGui::BeginMenu("Window")) {
ImGui::EndMenu();
}
}
void Help() {
if (ImGui::BeginMenu("Help")) {
ImGui::EndMenu();
}
}
~MainMenuBar() { ImGui::EndMainMenuBar(); } ~MainMenuBar() { ImGui::EndMainMenuBar(); }
private: private:
char* path = nullptr; char* path = nullptr;

View File

@ -17,6 +17,11 @@
typedef void ( *voidFunction ) (void); typedef void ( *voidFunction ) (void);
using namespace YoggieEngine; using namespace YoggieEngine;
auto matrix = glm::mat4(1.0f);
auto worldOrigin = glm::mat4(1.0f);
auto projection = glm::perspective(45.0f, 0.89f, 0.001f, 1.0f);
auto view = glm::mat4(1.0f);
inline void ComponentView(const std::string& componentName, voidFunction func) inline void ComponentView(const std::string& componentName, voidFunction func)
{ {
ImGuiWindowFlags_ window_flags = ImGuiWindowFlags_None; ImGuiWindowFlags_ window_flags = ImGuiWindowFlags_None;
@ -123,28 +128,108 @@ public:
} }
}; };
class Viewport : EditorWindow { class Viewport : EditorWindow {
public: public:
Viewport (Framebuffer& fb) : EditorWindow("SceneView") { Viewport (Framebuffer& fb, Camera cam ) : EditorWindow("SceneView")
ImGui::Image( {
ImVec2 WinPos = ImGui::GetWindowPos();
ImVec2 ContentRegionMin = ImGui::GetWindowContentRegionMin();
ImVec2 ContentRegionMax = ImGui::GetWindowContentRegionMax();
ImVec2 ScreenSpaceMin = { ContentRegionMin.x + WinPos.x, ContentRegionMin.y + WinPos.y };
ImVec2 ScreenSpaceMax = { ContentRegionMax.x + WinPos.x,ContentRegionMax.y + WinPos.y };
ImGui::Image(
(void*)(intptr_t)fb.GetColourAttachment(), (void*)(intptr_t)fb.GetColourAttachment(),
ImVec2{ (float)ImGui::GetWindowWidth(),(float)ImGui::GetWindowHeight() } ImVec2{ (float)ImGui::GetWindowWidth(),(float)ImGui::GetWindowHeight() }
); );
//ImGuizmo::SetDrawlist();
//ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); ImGuizmo::Enable(true);
//ImGuizmo::Enable(true); ImGuizmo::SetRect(ScreenSpaceMin.x, ScreenSpaceMin.y,ContentRegionMax.x, ContentRegionMax.y);
//ImGuizmo::Manipulate(glm::value_ptr(view), glm::value_ptr(projection), ImGuizmo::TRANSLATE, ImGuizmo::WORLD, glm::value_ptr(trans));
ImGuizmo::ViewManipulate(glm::value_ptr(cam.ViewMatrix), 1, { ScreenSpaceMin.x,ScreenSpaceMin.y }, { 90,90 }, 0x22CCCCCC);
ImGuizmo::DrawGrid(glm::value_ptr(cam.ViewMatrix), glm::value_ptr(cam.ProjectionMatrix), glm::value_ptr(worldOrigin), 100.0f);
// Matrix is the model matrix we would want to manipulate
ImGuizmo::Manipulate(glm::value_ptr(cam.ViewMatrix), glm::value_ptr(cam.ProjectionMatrix), ImGuizmo::TRANSLATE, ImGuizmo::WORLD, glm::value_ptr(matrix));
} }
}; };
int selectedGfxAPI = 0;
int selectedPhysicsEngine = 0;
glm::vec3 Gravity = glm::vec3(0.0f, -9.81f, 0.0f);
bool ShowAdvancedOptions = false;
bool DebugEngine = false;
class Settings : EditorWindow { class Settings : EditorWindow {
public: public:
Settings() : EditorWindow("Settings") { Settings() : EditorWindow("Settings")
ImGui::LabelText("##title-settings", "Fine grain control over your engine... "); {
ImGui::LabelText("##title-settings", "Fine grain control over the engine!");
if (ImGui::BeginCombo("Graphics API", GraphicsAPI[selectedGfxAPI])) {
for (int i = 0; i < 3; i++) {
bool isSelected = i == selectedGfxAPI;
if (ImGui::Selectable(GraphicsAPI[i], isSelected)) {
selectedGfxAPI = i;
}
if(isSelected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ImGui::NewLine();
if (ImGui::BeginCombo("Physics Engine", PhysicsEngine[selectedPhysicsEngine])) {
for (int i = 0; i < 2; i++) {
bool isSelected = i == selectedPhysicsEngine;
if (ImGui::Selectable(PhysicsEngine[i], isSelected)) {
selectedGfxAPI = i;
}
if (isSelected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ImGui::InputFloat3("Gravity", glm::value_ptr(Gravity));
ImGui::NewLine();
if (ImGui::Button("Show Advanced options ")) {
ShowAdvancedOptions = !ShowAdvancedOptions;
}
if (ShowAdvancedOptions)
{
ImGui::Checkbox("Debug Engine", &DebugEngine);
}
} }
private:
const char* PhysicsEngine[2] = {
"PhysX",
"Jolt Physics"
};
const char* GraphicsAPI[3] = {
"OpenGL",
"Vulkan",
"Metal (Apple)"
};
}; };
class ProjectInfo : EditorWindow { class ProjectInfo : EditorWindow {
@ -183,6 +268,9 @@ public:
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.f, 0.f, 0.f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.f, 0.f, 0.f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.f, 1.f, 1.f, 0.2f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.f, 1.f, 1.f, 0.2f));
Texture folderIcon = Texture("rsc/folderIcon.png");
Texture assetIcon = Texture("rsc/assetIcon.png");
int row = 0; int row = 0;
int column = 0; int column = 0;
@ -197,14 +285,14 @@ public:
if (asset.isFolder) { if (asset.isFolder) {
ImGui::ImageButton( ImGui::ImageButton(
(ImTextureID)(Texture("rsc/folderIcon.png")).GetID(), (ImTextureID)folderIcon.GetID(),
ImVec2{ (float)iconSize,(float)iconSize }); ImVec2{ (float)iconSize,(float)iconSize });
ImGui::Text(asset.GetName(), row); ImGui::Text(asset.GetName(), row);
} }
else { else {
ImGui::ImageButton( ImGui::ImageButton(
(ImTextureID)(Texture("rsc/assetIcon.png")).GetID(), (ImTextureID)assetIcon.GetID(),
ImVec2{ (float)iconSize, (float)iconSize }); ImVec2{ (float)iconSize, (float)iconSize });
ImGui::Text(asset.GetName(), row); ImGui::Text(asset.GetName(), row);
@ -217,12 +305,58 @@ public:
ImGui::PopStyleColor(3); ImGui::PopStyleColor(3);
ImGui::EndTable(); ImGui::EndTable();
const GLuint textures[2]{ assetIcon.GetID(), folderIcon.GetID() };
glDeleteTextures(2, textures );
} }
} }
private: private:
static Texture folderIcon;
static Texture AssetIcon;
int iconSize = 60; int iconSize = 60;
}; };
#define RuntimeControlWindowFlags (ImGuiWindowFlags_)(ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse)
struct ButtonInfo {
const char* Name;
ImVec4 Color;
};
class RuntimeControls : EditorWindow {
public:
RuntimeControls() : EditorWindow("RuntimeControls", RuntimeControlWindowFlags) {
ImGui::SameLine((ImGui::GetWindowContentRegionMax().x / 2) - ( numButtons * buttonSize.x ));
for (int i = 0; i < numButtons; i++) {
ImVec4 color = button[i].Color;
ImGui::PushStyleColor(ImGuiCol_Button, color);
const float strengthIncrease = 1.5f;
ImGui::PushStyleColor(
ImGuiCol_ButtonHovered,
ImVec4{
color.x * strengthIncrease,
color.y * strengthIncrease,
color.z * strengthIncrease,
color.w
}
);
if (ImGui::Button(button[i].Name, buttonSize)) {
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::SameLine();
}
}
private:
ImVec2 buttonSize = ImVec2{ 90 ,25 };
unsigned int numButtons = 2;
ButtonInfo button[2] = {
{"Play" , ImVec4{ 0.001 * 12 , 0.001 * 201 , 0.001* 69, 1.0f}},
{"Simulate", ImVec4{ 0.001 * 14, 0.001 * 157, 0.001 * 201, 1.0f}}
};
};

View File

@ -1,5 +1,6 @@
#include "../../YoggieEngine/src/EntryPoint.h" #include "../../YoggieEngine/src/EntryPoint.h"
#include "../../YoggieEngine/src/AssetManager/ModelImporter.h" #include "../../YoggieEngine/src/AssetManager/ModelImporter.h"
#include "../../YoggieEngine/src/Physics/Physics.h"
#include <nfd.h> #include <nfd.h>
@ -18,105 +19,64 @@
const unsigned int MS_PER_UPDATE = 2; const unsigned int MS_PER_UPDATE = 2;
void CreateTestProject(std::unique_ptr<Project>& project, Scene& scene); void CreateTestProject(std::unique_ptr<Project>& project, Scene& scene);
RendererConfig EditorSceneRendererConfig{
1200, // Screen Width
700, // Screen Height
glm::vec3{0,0,0}, // Clear Color
true // Depth testing
};
class Editor : public Application { class Editor : public Application {
public: public:
Editor() : Application("Editor"){ Editor()
} : Application("Editor"),
AppWindow(1200,700),
void Run() override framebuffer(new Framebuffer(1200,700)),
viewportRenderer(EditorSceneRendererConfig),
EditorGUIRenderer(AppWindow),
Selected((entt::entity)-1)
{ {
viewportRenderer.setCurrentFrameBuffer(*framebuffer);
auto NativeEditorWindow = NativeWindow(1200, 700);
framebuffer = new Framebuffer(800, 600);
auto renderer = Renderer(RendererConfig{
1200, // Screen Width
700, // Screen Height
glm::vec3{0,0,0}, // Clear Color
true // Depth testing
});
auto GuiRenderer = GUIRenderer(NativeEditorWindow);
Selected = (entt::entity)-1;
CreateTestProject(CurrentProject, ActiveScene);
ActiveScene.Start();
renderer.setCurrentFrameBuffer(*framebuffer);
double previous = glfwGetTime();
double lag = 0.0;
while (!NativeEditorWindow.WindowShouldClose())
{
double current = glfwGetTime();
double elapsed = current - previous;
previous = current;
lag += elapsed;
NativeEditorWindow.Poll();
while (lag >= MS_PER_UPDATE)
{
ActiveScene.Update();
lag -= MS_PER_UPDATE;
}
// submit DrawCommands for all render3DComponents
auto group = ActiveScene.getReg().view<TransformComponent, Render3DComponent>();
group.each([&renderer](auto enity, TransformComponent& t, Render3DComponent& renderComponent) {
renderer.Submit(renderComponent, t);
});
renderer.Render();
GuiRenderer.Begin();
RenderGUI();
GuiRenderer.End();
NativeEditorWindow.SwapBuffers();
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
}
delete framebuffer;
ActiveScene.Stop();
} }
void RenderScene() {
// submit DrawCommands for all render3DComponents
auto group = ActiveScene.getReg().view<TransformComponent, Render3DComponent>();
group.each([&](auto enity, TransformComponent& t, Render3DComponent& renderComponent) {
viewportRenderer.Submit(renderComponent, t);
});
void RenderGUI() { viewportRenderer.Render();
}
void RenderEditorGUI() {
EditorGUIRenderer.Begin();
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
// Show a menu bar // Show a menu bar
{ {
MainMenuBar menuBar= MainMenuBar(); MainMenuBar menuBar = MainMenuBar();
menuBar.ApplicationMenu(CurrentProject); menuBar.ApplicationMenu(CurrentProject);
menuBar.SceneMenu(CurrentProject, ActiveScene); menuBar.SceneMenu(CurrentProject, ActiveScene);
/*menuBar.SelectMenu(); menuBar.SelectMenu();
menuBar.WindowMenu(); menuBar.WindowMenu();
menuBar.DebugMenu(); menuBar.DebugMenu();
menuBar.Help(); menuBar.Help();
*/
} }
{ {
ProjectInfo projectInfo(*(CurrentProject.get())); ProjectInfo projectInfo(*(CurrentProject.get()));
} }
{ {
Viewport sceneview = Viewport(*framebuffer); Viewport sceneview = Viewport(*framebuffer, viewportRenderer.getCamera());
} }
{
RuntimeControls rc = RuntimeControls();
}
{ {
SceneExplorer explorer(Selected, ActiveScene); SceneExplorer explorer(Selected, ActiveScene);
} }
@ -132,11 +92,11 @@ public:
} }
{ {
Settings settings(); Settings settings = Settings();
} }
{ {
// AssetFinder assetsView = AssetFinder(); // AssetFinder assetsView = AssetFinder();
} }
@ -147,15 +107,74 @@ public:
ImGui::ShowDemoWindow(); ImGui::ShowDemoWindow();
ImGui::ShowMetricsWindow(); ImGui::ShowMetricsWindow();
EditorGUIRenderer.End();
}
void Run() override
{
CreateTestProject(CurrentProject, ActiveScene);
ActiveScene.Start();
// Create the physics engine demo!
Physics Physics;
//Physics.Demo();
double previous = glfwGetTime();
double lag = 0.0;
while (!AppWindow.WindowShouldClose())
{
double current = glfwGetTime();
double elapsed = current - previous;
previous = current;
lag += elapsed;
AppWindow.Poll();
if (SimulatePhysics)
{
Physics.Step(1.0f / 60.0f);
}
while (lag >= MS_PER_UPDATE)
{
ActiveScene.Update();
lag -= MS_PER_UPDATE;
}
RenderScene();
RenderEditorGUI();
AppWindow.SwapBuffers();
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
}
delete framebuffer;
ActiveScene.Stop();
} }
private: private:
NativeWindow AppWindow;
Framebuffer* framebuffer;
Renderer viewportRenderer;
GUIRenderer EditorGUIRenderer;
// Editor State
bool SimulatePhysics = false;
entt::entity Selected;
std::unique_ptr<Project> CurrentProject; std::unique_ptr<Project> CurrentProject;
Scene ActiveScene; Scene ActiveScene;
entt::entity Selected;
Framebuffer* framebuffer ;
}; };
@ -180,7 +199,7 @@ void CreateTestProject(std::unique_ptr<Project>& project, Scene& scene ) {
// Create a cube // Create a cube
auto model = importer.Import("build/Debug/Models/Cube.obj"); auto model = importer.Import("build/Debug/Models/Cube.obj");
auto cube = scene.AddEntity("cube"); auto cube = scene.AddEntity("Cube");
auto& render3DComponent = cube.AddComponent<Render3DComponent>(); auto& render3DComponent = cube.AddComponent<Render3DComponent>();
render3DComponent.mesh = *(model->renderable->mesh); render3DComponent.mesh = *(model->renderable->mesh);

View File

@ -7,7 +7,9 @@
<img src="Screenshots/screen1.png" width="300"></img> \ <img src="Screenshots/screen1.png" width="300"></img> \
<img src="Screenshots/screen2.png" width="300"></img> \ <img src="Screenshots/screen2.png" width="300"></img> \
<img src="Screenshots/YoggieEditor.png" width="300"></img> <img src="Screenshots/YoggieEditor.png" width="300"></img> \
<img src="Screenshots/YoggieEditor_workingGuizmo.png" width="300"></img> \
<img src="Screenshots/YoggieEditorV0.2.png" width="300"></img>
## Planning ## Planning
see [TODO](docs/TODO.md) \ see [TODO](docs/TODO.md) \
see [Features](Features.md) see [Features](Features.md)

BIN
Screenshots/YoggieEditorV0.2.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Screenshots/YoggieEditor_workingGuizmo.png (Stored with Git LFS) Normal file

Binary file not shown.