244 lines
6.8 KiB
C++
244 lines
6.8 KiB
C++
#include "glad/gl.h"
|
|
#include "GLFW/glfw3.h"
|
|
|
|
#include "spdlog/spdlog.h"
|
|
|
|
#include "glm/glm.hpp"
|
|
#include "glm/ext/matrix_clip_space.hpp"
|
|
|
|
#define STB_IMAGE_IMPLEMENTATION
|
|
#include "AssetRegistry.h"
|
|
#include "stb_image.h"
|
|
|
|
#include "Camera.h"
|
|
#include "Components.h"
|
|
#include "EditorContext.h"
|
|
#include "FreeCameraController.h"
|
|
#include "InputManager.h"
|
|
#include "ModelManager.h"
|
|
#include "ProjectManifest.h"
|
|
#include "ProjectManifestFile.h"
|
|
#include "Scene.h"
|
|
#include "ShaderManager.h"
|
|
#include "ShaderProgram.h"
|
|
#include "TextureManager.h"
|
|
|
|
#include "UIManager.h"
|
|
#include "ui/UIEntityInspector.h"
|
|
#include "ui/UIMenuBar.h"
|
|
#include "ui/UISceneGraph.h"
|
|
#include "ui/UISceneViewer.h"
|
|
|
|
#include <filesystem>
|
|
|
|
const char* B_ENGINE_VERSION = "v0.0.3";
|
|
|
|
GLFWwindow* gWindow = nullptr;
|
|
int gWindowWidth = 1920;
|
|
int gWindowHeight = 1080;
|
|
|
|
int glVersionMajor = 0;
|
|
int glVersionMinor = 0;
|
|
|
|
float gAspectRatio = 0.f;
|
|
|
|
float gMouseSensitivity = 0.1f;
|
|
|
|
std::unique_ptr<ProjectManifest> gCurrentProject {nullptr};
|
|
|
|
Scene gScene{};
|
|
EditorContext gEditorCtx{};
|
|
|
|
Camera gCamera {};
|
|
FreeCameraController gEditorCameraController{};
|
|
|
|
void glfw_error_callback(int error, const char* description);
|
|
void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
|
void glfw_framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
|
|
|
void init_glfw();
|
|
void create_main_window();
|
|
void load_gl();
|
|
void load_inputs();
|
|
void init_editor_camera();
|
|
void loop();
|
|
|
|
void create_entity(entt::entity parent);
|
|
void open_project(std::string_view _path);
|
|
|
|
auto xAxis = glm::vec3{1.f, 0.f, 0.f};
|
|
auto yAxis = glm::vec3{0.f, 1.f, 0.f};
|
|
auto zAxis = glm::vec3{0.f, 0.f, 1.f};
|
|
|
|
int main() {
|
|
spdlog::info("b_engine {} start", B_ENGINE_VERSION);
|
|
|
|
init_glfw();
|
|
|
|
create_main_window();
|
|
|
|
load_gl();
|
|
|
|
stbi_set_flip_vertically_on_load(true);
|
|
|
|
load_inputs();
|
|
|
|
UIManager::init(gWindow);
|
|
auto* menuBar = UIManager::add_ui_panel<UIMenuBar>("menu_bar");
|
|
menuBar->create_entity = create_entity;
|
|
menuBar->open_project = open_project;
|
|
UIManager::add_ui_panel<UISceneViewer>("scene_viewer");
|
|
UIManager::add_ui_panel<UISceneGraph>("scene_graph");
|
|
UIManager::add_ui_panel<UIEntityInspector>("entity_inspector");
|
|
|
|
gEditorCameraController.set_camera(gCamera);
|
|
gEditorCameraController.look_sensitivity = 0.2;
|
|
gEditorCameraController.movement_speed = 0.2;
|
|
InputManager::add_mouse_listener([](float xoff, float yoff) {
|
|
gEditorCameraController.on_mouse_delta(xoff, yoff);
|
|
});
|
|
|
|
gEditorCtx.scene = &gScene;
|
|
gEditorCtx.window = gWindow;
|
|
gEditorCtx.selectedEntity = entt::null;
|
|
|
|
loop();
|
|
|
|
ShaderManager::shaders.clear();
|
|
TextureManager::textures.clear();
|
|
ModelManager::models.clear();
|
|
|
|
glfwDestroyWindow(gWindow);
|
|
glfwTerminate();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void glfw_error_callback(int error, const char* description) {
|
|
spdlog::error("glfw error: {}", description);
|
|
}
|
|
|
|
void glfw_framebuffer_size_callback(GLFWwindow *window, int width, int height) {
|
|
glViewport(0, 0, width, height);
|
|
gAspectRatio = (float)width / (float)height;
|
|
gCamera.update_aspect_ratio(gAspectRatio);
|
|
}
|
|
|
|
void init_glfw() {
|
|
if (!glfwInit()) {
|
|
spdlog::error("could not initialize glfw");
|
|
std::exit(1);
|
|
}
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
glfwWindowHint(GLFW_SAMPLES, 4);
|
|
|
|
glfwSetErrorCallback(glfw_error_callback);
|
|
}
|
|
|
|
void create_main_window()
|
|
{
|
|
std::string title = fmt::format("b_engine {}", B_ENGINE_VERSION);
|
|
gWindow = glfwCreateWindow(gWindowWidth, gWindowHeight, title.c_str(), nullptr, nullptr);
|
|
if (!gWindow) {
|
|
spdlog::error("failed to create glfw window");
|
|
std::exit(1);
|
|
}
|
|
|
|
glfwMakeContextCurrent(gWindow);
|
|
|
|
glfwSetKeyCallback(gWindow, InputManager::key_callback);
|
|
glfwSetCursorPosCallback(gWindow, InputManager::mouse_pos_callback);
|
|
|
|
glfwSetFramebufferSizeCallback(gWindow, glfw_framebuffer_size_callback);
|
|
}
|
|
|
|
void load_gl()
|
|
{
|
|
int version = gladLoadGL(glfwGetProcAddress);
|
|
glVersionMajor = GLAD_VERSION_MAJOR(version);
|
|
glVersionMinor = GLAD_VERSION_MINOR(version);
|
|
spdlog::info("gl version {}.{}", glVersionMajor, glVersionMinor);
|
|
|
|
if (gWindow)
|
|
{
|
|
int fbWidth, fbHeight;
|
|
glfwGetFramebufferSize(gWindow, &fbWidth, &fbHeight);
|
|
gAspectRatio = (float)fbWidth / (float)fbHeight;
|
|
}
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_MULTISAMPLE);
|
|
}
|
|
|
|
void init_editor_camera() {
|
|
gCamera = {{10.f, 10.f, 10.f}, 0, 0, gAspectRatio};
|
|
gCamera.rotate_yaw(-135.f);
|
|
gCamera.rotate_pitch(-35.f);
|
|
}
|
|
|
|
void load_inputs() {
|
|
InputManager::generate_input_action("move_forward", {{GLFW_KEY_W, KEY_DOWN}});
|
|
InputManager::generate_input_action("move_backward", {{GLFW_KEY_S, KEY_DOWN}});
|
|
InputManager::generate_input_action("move_right", {{GLFW_KEY_D, KEY_DOWN}});
|
|
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}});
|
|
}
|
|
|
|
void loop() {
|
|
while (!glfwWindowShouldClose(gWindow)) {
|
|
// input
|
|
glfwPollEvents();
|
|
|
|
// update
|
|
UIManager::update(gEditorCtx);
|
|
gEditorCameraController.update(gEditorCtx);
|
|
|
|
if (gCamera.aspect_ratio() != gEditorCtx.viewportAspectRatio) {
|
|
gCamera.update_aspect_ratio(gEditorCtx.viewportAspectRatio);
|
|
}
|
|
|
|
gScene.update_transforms();
|
|
|
|
const auto* uiScenePanel = dynamic_cast<UISceneViewer*>(UIManager::get_ui_panel("scene_viewer").get());
|
|
if (uiScenePanel) {
|
|
uiScenePanel->bind_fbo();
|
|
}
|
|
|
|
// draw
|
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
// const auto shader = ShaderManager::shaders["phong_shader"];
|
|
// gScene.draw_scene(shader.get());
|
|
|
|
glBindVertexArray(0);
|
|
ShaderProgram::unbind();
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
UIManager::draw();
|
|
|
|
// end frame
|
|
glfwSwapBuffers(gWindow);
|
|
}
|
|
}
|
|
|
|
void create_entity(entt::entity parent) {
|
|
gScene.create_game_object(parent);
|
|
}
|
|
|
|
void open_project(std::string_view _path) {
|
|
const std::filesystem::path projectFilePath {_path};
|
|
gCurrentProject = ProjectManifestFile::load(_path);
|
|
gCurrentProject->projectDirectory = projectFilePath.parent_path();
|
|
|
|
std::filesystem::path assetPath = gCurrentProject->projectDirectory.append(gCurrentProject->assetFolder);
|
|
AssetRegistry::read_directory(assetPath);
|
|
|
|
const std::string title = fmt::format("project \"{}\" | b_engine {}", gCurrentProject->name, B_ENGINE_VERSION);
|
|
glfwSetWindowTitle(gWindow, title.c_str());
|
|
}
|