diff --git a/.255.cache.bin b/.255.cache.bin new file mode 100644 index 000000000..43721a4a6 Binary files /dev/null and b/.255.cache.bin differ diff --git a/.gitmodules b/.gitmodules index f454c8c3c..a0a21affc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "modules/thirdparty-yaml-cpp/yaml-cppmodules/thirdparty-yaml-cpp/yaml-cpp"] - path = modules/thirdparty-yaml-cpp/yaml-cppmodules/thirdparty-yaml-cpp/yaml-cpp - url = https://github.com/EldarMuradov/yaml-cpp.git [submodule "modules/thirdparty-yaml-cpp/yaml-cpp"] path = modules/thirdparty-yaml-cpp/yaml-cpp url = https://github.com/EldarMuradov/yaml-cpp.git diff --git a/CMakeLists.txt b/CMakeLists.txt index d3ad87f71..580741eae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.12) set(ERA_ENGINE_PATH ${CMAKE_SOURCE_DIR}) include(cmake/common.cmake) +include(cmake/deploy.cmake) project(EraEngine VERSION 1.0) @@ -17,5 +18,9 @@ add_subdirectory(modules/physics) add_subdirectory(apps/editor) add_subdirectory(apps/example_game) +add_subdirectory(apps/assets_compiler) + +era_add_deploy_target(editor) +era_add_deploy_target(example_game) set_property(GLOBAL PROPERTY USE_FOLDERS ON) \ No newline at end of file diff --git a/README.md b/README.md index cd811272c..c96c3918c 100644 --- a/README.md +++ b/README.md @@ -1 +1,151 @@ -# Engine \ No newline at end of file + +![EraEngine Logo](https://github.com/EldarMuradov/EldarMuradov/blob/a4d76f9ec241f35d76237f3e637cbf1921de5d2d/Editor.png) + +![EraEngine Logo](https://github.com/EldarMuradov/EldarMuradov/blob/99a6272b7b5f123c8f20b7c39f773714f79810cd/MESH_EDITOR.png) + +![EraEngine Logo](https://github.com/EldarMuradov/EldarMuradov/blob/56c453501a5edb8bdbd7747548e99b94ff188e14/AKT2.png) + + +# Era Game Engine + +[![C++](https://img.shields.io/badge/language-C%2B%2B-%23f34b7d.svg?style=plastic)](https://en.wikipedia.org/wiki/C%2B%2B) +[![x64](https://img.shields.io/badge/arch-x64-red.svg?style=plastic)](https://en.wikipedia.org/wiki/X64) + +platforms + +![Build workflow](https://github.com/EldarMuradov/EraEngine/actions/workflows/cmake-windows-platform.yml/badge.svg) + +# About + +Era Engine is a modern ECS-based game engine that provides developers with powerful tools for creating 2D/3D games. It includes the following features and functionality: + +### Entity Component System: +Era Engine uses ECS to manage game objects and their behavior. This allows developers to easily create and modify complex systems in the game. + +### Rendering: +The engine uses DirectX 12 to provide high-quality and efficient rendering, allowing you to create visually appealing games with advanced graphical effects. DLSS 3.5 and FSR 2.0 supported. + +### Physics: +Integration with PhysX 5.3.1 and CUDA provides realistic simulation of game physics, including collisions, GJK (overlapping, raycasting etc), gravity, aggregates, articulations, soft bodies, GPU particles, GPU clothes, joints, Blast Physics Destructions, Mesh destructions, ragdolls, vehicles, CPU-based tasks, physics event system etc. + +### User Interface: +ImGui is integrated into the engine to create intuitive and customizable user interfaces in games. + +## Audio: +Engine provides API and tools to work with 3D Audio. You can customize all audio settings and preferences to create realistic high quality sounds. + +### Scripting: +Era Engine uses .NET 8.0 Native AOT and Runtime. This allows developers to write scripts in C# with all the benefits of .NET, including high performance and a rich class library. + +# Dependencies + +-PhysX 5.3.1 + +-DirectX 12 + +-EnTT + +-ImGUI + +-CUDA + +-Blast + +-.NET 8.0 (Native AOT and Runtime) + +# Features + +-Real-time raytracing (DXR) + +-DLSS 3.5 + +-FSR 2.0 + +-Rigidbodies and colliders + +-Fluid Physics + +-Blast Physics Destructions + +-PBR Rendering + +-GPU PBD Particle Systems + +-GPU PBD Clothing Systems + +-Physics Joints + +-Physics Aggregates + +-CPU Tasks + +-GPU Physics + +-Forward rendering + +-Decals + +-Material editing + +-ECS + +-Horizon-based ambient occlusion + +-Screen space shadows + +-CCD + +-Skeletal animation + +-Editor + +-MSAA + +-Building + +-Spot lights + +-Resource system + +-Temporal anti-aliasing + +-Mesh shaders + +-Mesh and Audio Editors + +-Scene management + +-Saving system + +-Undoable components + +-Custom physics engine + +-.NET 8 scripting + +-Job system + +-Screen space reflections + +-Path tracing + +-Cascaded shadow maps + +-GI + +-Point lights + +-Audio system + +-Child-parent system + +-Post processing + +# TODO: + +-Console support + +-Networking components + + +Some other researches and repositories were used while developing game engine. Thanks P. Kurth, O. Ocornut, M. Caini, NVIDIA, Ubisoft and Microsoft. diff --git a/apps/assets_compiler/CMakeLists.txt b/apps/assets_compiler/CMakeLists.txt new file mode 100644 index 000000000..a6fc7163f --- /dev/null +++ b/apps/assets_compiler/CMakeLists.txt @@ -0,0 +1,12 @@ +include(${CMAKE_SOURCE_DIR}/cmake/common.cmake) + +era_begin(assets_compiler "APP") + require_thirdparty_module(assets_compiler EnTT) + require_thirdparty_module(assets_compiler yaml-cpp) + require_thirdparty_module(assets_compiler rttr_core) + require_thirdparty_module(assets_compiler DirectXTex) + require_module(assets_compiler base) + require_module(assets_compiler core) + + target_include_directories(assets_compiler PUBLIC modules/thirdparty-imgui/imgui) +era_end(assets_compiler) \ No newline at end of file diff --git a/apps/assets_compiler/src/compiler/main.cpp b/apps/assets_compiler/src/compiler/main.cpp new file mode 100644 index 000000000..e946b3459 --- /dev/null +++ b/apps/assets_compiler/src/compiler/main.cpp @@ -0,0 +1,90 @@ +// Copyright (c) 2023-present Eldar Muradov. All rights reserved. +#include +#include + +#include + +#include +#include + +#include +#include + +int main(int argc, char** argv) +{ + using namespace era_engine; + using namespace clara; + + try + { + fs::path path; + bool verbose = false; + + Parser cli; + cli += Opt(verbose, "verbose")["-v"]["--verbose"]("Enable verbose logging"); + cli += Opt(path, "path")["-p"]["--path"]("Path to asset"); + + auto result = cli.parse(Args(argc, argv)); + if (!result) + { + std::cerr << "Error in command line: " << result.errorMessage() << std::endl; + } + + path = get_full_path(path); + + if (!fs::exists(path)) + { + std::cerr << "Could not find file '" << path << "'.\n"; + return EXIT_FAILURE; + } + + std::string extension = path.extension().string(); + + fs::path cached_filename = path; + cached_filename.replace_extension("." + std::to_string(mesh_flag_default) + ".cache.bin"); + fs::path cache_filepath = L"asset_cache" / cached_filename; + + if (fs::exists(cache_filepath)) + { + auto last_cache_write_time = fs::last_write_time(cache_filepath); + auto last_original_write_time = fs::last_write_time(path); + + if (last_cache_write_time > last_original_write_time) + { + std::cout << "Asset is already compiled! \n"; + return EXIT_SUCCESS; + } + } + + std::cout << "Preprocessing asset '" << path << "' for faster loading next time.\n"; + + ModelAsset result_mesh; + + std::transform(extension.begin(), extension.end(), extension.begin(), + [](char c) { return std::tolower(c); }); + if (extension == ".fbx") + { + result_mesh = loadFBX(path, mesh_flag_default); + } + else if (extension == ".obj") + { + result_mesh = loadOBJ(path, mesh_flag_default); + } + + fs::create_directories(cache_filepath.parent_path()); + writeBIN(result_mesh, cache_filepath); + } + catch (const std::exception& ex) + { + std::cerr << ex.what() << "\n"; + + std::ofstream output("logs/compiler_error_log.txt"); + output << "Runtime Error>" << ex.what() << std::endl; + output.close(); + + std::this_thread::sleep_for(std::chrono::duration(5000.0f)); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/apps/editor/CMakeLists.txt b/apps/editor/CMakeLists.txt index 00158832e..d2ad66fb7 100644 --- a/apps/editor/CMakeLists.txt +++ b/apps/editor/CMakeLists.txt @@ -1,6 +1,10 @@ include(${CMAKE_SOURCE_DIR}/cmake/common.cmake) era_begin(editor "APP") + require_thirdparty_module(editor EnTT) + require_thirdparty_module(editor yaml-cpp) + require_thirdparty_module(editor rttr_core) + require_thirdparty_module(editor DirectXTex) require_module(editor base) require_module(editor core) require_module(editor physics) diff --git a/apps/editor/src/editor/drag_n_drop_system.cpp b/apps/editor/src/editor/drag_n_drop_system.cpp new file mode 100644 index 000000000..9085c208e --- /dev/null +++ b/apps/editor/src/editor/drag_n_drop_system.cpp @@ -0,0 +1,77 @@ +#include "editor/drag_n_drop_system.h" +#include "editor/file_utils.h" + +#include + +#include +#include + +#include + +#include + +#include +#include + +#define IMGUI_DEFINE_MATH_OPERATORS +#include +#include +#include +#include +#include +#include + +namespace era_engine +{ + + RTTR_REGISTRATION + { + using namespace rttr; + + registration::class_("DragNDropSystem") + .constructor()(policy::ctor::as_raw_ptr) + .method("update", &DragNDropSystem::update)(metadata("update_group", update_types::INPUT), metadata("After", std::vector{"InputSystem::update"})); + } + + DragNDropSystem::DragNDropSystem(World* _world) + : System(_world) + { + + } + + DragNDropSystem::~DragNDropSystem() + { + } + + void DragNDropSystem::init() + { + renderer_holder_rc = world->add_root_component(); + ASSERT(renderer_holder_rc != nullptr); + } + + void DragNDropSystem::update(float dt) + { + //float render_width = static_cast(renderer_holder_rc->width); + //float render_height = static_cast(renderer_holder_rc->height); + + //// The drag&drop outline is rendered around the drop target. Since the image fills the frame, the outline is outside the window + //// and thus invisible. So instead this (slightly smaller) Dummy acts as the drop target. + //// Important: This is below the input processing, so that we don't override the current element id. + //ImGui::SetCursorPos(ImVec2(4.5f, 4.5f)); + //ImGui::Dummy(ImVec2(render_width - 9.0f, render_height - 9.0f)); + // + //if (ImGui::BeginDragDropTarget()) + //{ + // if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(EDITOR_ICON_MESH)) + // { + // EditorFileUtils::handle_file_drop((const char*)payload->Data, world); + // } + // if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(EDITOR_ICON_IMAGE_HDR)) + // { + // EditorFileUtils::handle_file_drop((const char*)payload->Data, world); + // } + // ImGui::EndDragDropTarget(); + //} + } + +} \ No newline at end of file diff --git a/apps/editor/src/editor/drag_n_drop_system.h b/apps/editor/src/editor/drag_n_drop_system.h new file mode 100644 index 000000000..ba3031f05 --- /dev/null +++ b/apps/editor/src/editor/drag_n_drop_system.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace era_engine +{ + class RendererHolderRootComponent; + + class DragNDropSystem final : public System + { + public: + DragNDropSystem(World* _world); + ~DragNDropSystem(); + + void init() override; + void update(float dt) override; + + ERA_VIRTUAL_REFLECT(System) + + private: + RendererHolderRootComponent* renderer_holder_rc = nullptr; + }; +} \ No newline at end of file diff --git a/apps/editor/src/editor/editor_init_system.cpp b/apps/editor/src/editor/editor_init_system.cpp new file mode 100644 index 000000000..0fdbd38ab --- /dev/null +++ b/apps/editor/src/editor/editor_init_system.cpp @@ -0,0 +1,68 @@ +#include "editor/editor_init_system.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include