entity editor, scene graph viewer, scene viewer basics done. Can rotate, translate and scale selected models.

This commit is contained in:
2026-05-11 22:24:47 -05:00
parent 5d78fd672e
commit cf916951f0
22 changed files with 864 additions and 291 deletions

View File

@@ -5,29 +5,26 @@
#include "glm/glm.hpp"
#include "glm/ext/matrix_clip_space.hpp"
#include "glm/ext/matrix_transform.hpp"
#include "entt/entt.hpp"
#define STB_IMAGE_IMPLEMENTATION
#include "Components.h"
#include "FreeCamera.h"
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include "imgui_internal.h"
#include "InputManager.h"
#include "stb_image.h"
#include "Model.h"
#include "Camera.h"
#include "Components.h"
#include "EditorContext.h"
#include "FreeCameraController.h"
#include "InputManager.h"
#include "ModelManager.h"
#include "Scene.h"
#include "ShaderManager.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "TextureManager.h"
#include "fmt/base.h"
#include "UIManager.h"
#include "ui/UIEntityInspector.h"
#include "ui/UIMenuBar.h"
#include "ui/UISceneGraph.h"
#include "ui/UISceneViewer.h"
GLFWwindow* gWindow = nullptr;
int gWindowWidth = 1920;
@@ -40,11 +37,10 @@ float gAspectRatio = 0.f;
float gMouseSensitivity = 0.1f;
FreeCamera gCamera {};
Camera gCamera {};
Scene gScene{};
bool gUiFirstRender = true;
EditorContext gEditorCtx{};
FreeCameraController gCameraController{};
void glfw_error_callback(int error, const char* description);
void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
@@ -53,14 +49,15 @@ void glfw_framebuffer_size_callback(GLFWwindow* window, int width, int height);
void init_glfw();
void create_main_window();
void load_gl();
void load_imgui();
void init_camera();
void init_scene();
void load_default_textures();
void load_shaders();
void load_inputs();
void load_default_models();
void loop();
void draw_ui();
void create_entity(entt::entity parent);
auto xAxis = glm::vec3{1.f, 0.f, 0.f};
auto yAxis = glm::vec3{0.f, 1.f, 0.f};
@@ -75,10 +72,6 @@ int main() {
load_gl();
load_imgui();
init_camera();
stbi_set_flip_vertically_on_load(true);
load_default_textures();
@@ -89,15 +82,26 @@ int main() {
load_default_models();
entt::entity dirLight = gScene.create_game_object();
auto& [direction, ambient, diffuse, specular] = gScene.attach_component<Components::DirectionalLight>(dirLight);
direction = {1, -1, 1};
ambient = {0.3f, 0.3f, 0.3f};
diffuse = {0.5f, 0.5f, 0.5f};
specular = {1.0f, 1.0f, 1.0f};
UIManager::init(gWindow);
UIMenuBar* menuBar = UIManager::add_ui_panel<UIMenuBar>("menu_bar");
menuBar->create_entity = create_entity;
UIManager::add_ui_panel<UISceneViewer>("scene_viewer");
UIManager::add_ui_panel<UISceneGraph>("scene_graph");
UIManager::add_ui_panel<UIEntityInspector>("entity_inspector");
auto& tag = gScene.fetch_component<Components::Tag>(dirLight);
tag.name = "directional light";
init_camera();
init_scene();
gCameraController.set_camera(gCamera);
gCameraController.look_sensitivity = 0.2;
gCameraController.movement_speed = 0.2;
InputManager::add_mouse_listener([](float xoff, float yoff) {
gCameraController.on_mouse_delta(xoff, yoff);
});
gEditorCtx.scene = &gScene;
gEditorCtx.window = gWindow;
gEditorCtx.selectedEntity = entt::null;
loop();
@@ -174,27 +178,23 @@ void load_gl()
glEnable(GL_MULTISAMPLE);
}
void load_imgui() {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(gWindow, true);
ImGui_ImplOpenGL3_Init("#version 330");
}
void init_camera() {
gCamera = {{5.f, 5.f, 5.f}, 0, 0, gAspectRatio};
gCamera = {{10.f, 10.f, 10.f}, 0, 0, gAspectRatio};
gCamera.rotate_yaw(-135.f);
gCamera.rotate_pitch(-35.f);
}
InputManager::add_mouse_listener([](float xoff, float yoff) {
gCamera.rotate_yaw(xoff * gMouseSensitivity);
gCamera.rotate_pitch(yoff * gMouseSensitivity);
});
void init_scene() {
gScene.set_active_camera(&gCamera);
const auto defaultLight = gScene.create_game_object();
auto& [name] = gScene.fetch_component<Components::Tag>(defaultLight);
name = "Directional Light";
auto& [direction, ambient, diffuse, specular] = gScene.attach_component<Components::DirectionalLight>(defaultLight);
direction = glm::vec3(-1, -1, -1);
ambient = glm::vec3(0.3);
diffuse = glm::vec3(0.7);
specular = glm::vec3(1.0);
}
void load_default_textures() {
@@ -224,7 +224,6 @@ void load_inputs() {
InputManager::generate_input_action("move_left", {{GLFW_KEY_A, KEY_DOWN}});
InputManager::generate_input_action("move_up", {{GLFW_KEY_SPACE, KEY_DOWN}});
InputManager::generate_input_action("move_down", {{GLFW_KEY_LEFT_SHIFT, KEY_DOWN}});
InputManager::generate_input_action("exit_application", {{GLFW_KEY_ESCAPE, KEY_DOWN}});
}
void load_default_models() {
@@ -236,147 +235,47 @@ void load_default_models() {
void loop() {
while (!glfwWindowShouldClose(gWindow)) {
// input
glfwPollEvents();
// check inputs
/*if (InputManager::check_action_performed("exit_application")) {
glfwSetWindowShouldClose(gWindow, true);
continue;
}*/
// update
UIManager::update(gEditorCtx);
gCameraController.update(gEditorCtx);
if (InputManager::check_action_performed("move_forward")) {
gCamera.move(FORWARD, .05);
if (gCamera.aspect_ratio() != gEditorCtx.viewportAspectRatio) {
gCamera.update_aspect_ratio(gEditorCtx.viewportAspectRatio);
}
if (InputManager::check_action_performed("move_backward")) {
gCamera.move(BACKWARD, .05);
gScene.update_transforms();
const auto* uiScenePanel = dynamic_cast<UISceneViewer*>(UIManager::get_ui_panel("scene_viewer").get());
if (uiScenePanel) {
uiScenePanel->bind_fbo();
}
if (InputManager::check_action_performed("move_left")) {
gCamera.move(LEFT, .05);
}
if (InputManager::check_action_performed("move_right")) {
gCamera.move(RIGHT, .05);
}
if (InputManager::check_action_performed("move_up")) {
gCamera.move(UP, .05);
}
if (InputManager::check_action_performed("move_down")) {
gCamera.move(DOWN, .05);
}
draw_ui();
// gl frame prep
// draw
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
const auto shader = ShaderManager::shaders["phong_shader"];
shader->bind();
shader->setMat4("projection", gCamera.projection());
shader->setMat4("view", gCamera.view());
shader->setVec3("viewPosition", gCamera.position());
gScene.draw_scene(shader.get());
glBindVertexArray(0);
ShaderProgram::unbind();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// gl end frame stuff
UIManager::draw();
// end frame
glfwSwapBuffers(gWindow);
}
}
void draw_ui() {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
{
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->Pos);
ImGui::SetNextWindowSize(viewport->Size);
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
ImGui::Begin("b_engine dockspace", nullptr, window_flags);
ImGui::PopStyleVar(2);
ImGuiID dockspace_id = ImGui::GetID("bengine_dockspace");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
if (gUiFirstRender) {
gUiFirstRender = false;
ImGui::DockBuilderRemoveNode(dockspace_id); // Clear any previous layout
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace);
ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size);
ImGuiID dock_main_id = dockspace_id; // The center remains for the game view
const ImGuiID dock_id_left =
ImGui::DockBuilderSplitNode(dock_main_id, ImGuiDir_Left, 0.2f, nullptr, &dock_main_id);
const ImGuiID dock_id_right =
ImGui::DockBuilderSplitNode(dock_main_id, ImGuiDir_Right, 0.25f, nullptr, &dock_main_id);
// Assign your windows to these specific dock IDs
ImGui::DockBuilderDockWindow("Hierarchy", dock_id_left);
ImGui::DockBuilderDockWindow("Inspector", dock_id_right);
ImGui::DockBuilderDockWindow("Scene", dock_main_id);
ImGui::DockBuilderFinish(dockspace_id);
}
ImGui::Begin("Hierarchy");
ImGui::Text("List of GameObjects...");
ImGui::End();
ImGui::Begin("Inspector");
ImGui::Text("Component Properties...");
ImGui::End();
ImGui::Begin("Scene");
ImGui::Text("This is where your 3D view goes!");
ImGui::End();
if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("New Scene")) {
/* Handle New File logic */
}
if (ImGui::MenuItem("Open Scene")) {
/* Handle Open logic */
}
ImGui::Separator(); // Adds a visual line between sections
if (ImGui::MenuItem("Save", "Ctrl+S")) {
/* Handle Save logic */
}
if (ImGui::MenuItem("Exit", "Alt+F4")) {
glfwSetWindowShouldClose(gWindow, true);
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Scene")) {
if (ImGui::MenuItem("New Scene Object")) {
gScene.create_game_object();
// Do other stuff here, open this entity in the entity editor, etc...
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
ImGui::End();
}
ImGui::Render();
}
void create_entity(entt::entity parent) {
auto entity = gScene.create_game_object(parent);
auto& drawable = gScene.attach_component<Components::Drawable>(entity);
drawable.model = ModelManager::models["vette"];
auto& transform = gScene.fetch_component<Components::Transform>(entity);
transform.scale = {0.1, 0.1, 0.1};
transform.dirty = true;
}