├── .gitignore ├── LICENSE ├── README.ZH-CN.md ├── README.md ├── engine ├── CMakeLists.txt ├── Fury │ ├── AnimationClip.cpp │ ├── AnimationClip.h │ ├── AnimationPlayer.cpp │ ├── AnimationPlayer.h │ ├── AnimationUtil.cpp │ ├── AnimationUtil.h │ ├── ArrayBuffers.cpp │ ├── ArrayBuffers.h │ ├── BoxBounds.cpp │ ├── BoxBounds.h │ ├── Buffer.cpp │ ├── Buffer.h │ ├── BufferManager.cpp │ ├── BufferManager.h │ ├── Camera.cpp │ ├── Camera.h │ ├── Collidable.h │ ├── Color.cpp │ ├── Color.h │ ├── Component.cpp │ ├── Component.h │ ├── Engine.cpp │ ├── Engine.h │ ├── Entity.cpp │ ├── Entity.h │ ├── EntityManager.h │ ├── EnumUtil.cpp │ ├── EnumUtil.h │ ├── FbxParser.cpp │ ├── FbxParser.h │ ├── FileUtil.cpp │ ├── FileUtil.h │ ├── Frustum.cpp │ ├── Frustum.h │ ├── Fury.h │ ├── GLLoader.cpp │ ├── GLLoader.h │ ├── GLTFDom.cpp │ ├── GLTFDom.h │ ├── Gui.cpp │ ├── Gui.h │ ├── InputUtil.cpp │ ├── InputUtil.h │ ├── Joint.cpp │ ├── Joint.h │ ├── Light.cpp │ ├── Light.h │ ├── Log.h │ ├── Macros.h │ ├── Material.cpp │ ├── Material.h │ ├── MathUtil.cpp │ ├── MathUtil.h │ ├── Matrix4.cpp │ ├── Matrix4.h │ ├── Mesh.cpp │ ├── Mesh.h │ ├── MeshRender.cpp │ ├── MeshRender.h │ ├── MeshUtil.cpp │ ├── MeshUtil.h │ ├── OcTree.cpp │ ├── OcTree.h │ ├── OcTreeNode.cpp │ ├── OcTreeNode.h │ ├── Pass.cpp │ ├── Pass.h │ ├── Pipeline.cpp │ ├── Pipeline.h │ ├── Plane.cpp │ ├── Plane.h │ ├── PrelightPipeline.cpp │ ├── PrelightPipeline.h │ ├── Quaternion.cpp │ ├── Quaternion.h │ ├── RenderQuery.cpp │ ├── RenderQuery.h │ ├── RenderUtil.cpp │ ├── RenderUtil.h │ ├── Scene.cpp │ ├── Scene.h │ ├── SceneManager.h │ ├── SceneNode.cpp │ ├── SceneNode.h │ ├── Serializable.cpp │ ├── Serializable.h │ ├── Shader.cpp │ ├── Shader.h │ ├── Signal.h │ ├── Singleton.h │ ├── SphereBounds.cpp │ ├── SphereBounds.h │ ├── Texture.cpp │ ├── Texture.h │ ├── ThreadUtil.cpp │ ├── ThreadUtil.h │ ├── Transform.cpp │ ├── Transform.h │ ├── TypeComparable.h │ ├── Uniform.cpp │ ├── Uniform.h │ ├── Vector4.cpp │ └── Vector4.h └── ThirdParty │ ├── ImGui │ ├── imconfig.h │ ├── imgui.cpp │ ├── imgui.h │ ├── imgui_demo.cpp │ ├── imgui_draw.cpp │ ├── imgui_fury.cpp │ ├── imgui_fury.h │ └── imgui_internal.h │ ├── LZ4 │ ├── LICENSE │ ├── lz4.c │ ├── lz4.h │ ├── lz4hc.c │ └── lz4hc.h │ └── STB │ ├── stb_image.h │ ├── stb_rect_pack.h │ ├── stb_textedit.h │ └── stb_truetype.h ├── examples ├── CMakeLists.txt ├── Demo.cpp └── bin │ ├── Resource │ ├── Pipeline │ │ └── DefferedLightingLambert.json │ ├── Scene │ │ ├── body.jpg │ │ ├── grass.jpg │ │ ├── james.fbx │ │ ├── outdoor.fbx │ │ ├── scene.bin │ │ ├── scene.json │ │ ├── tank.fbx │ │ ├── unspecified.png │ │ └── wheels.jpg │ └── Shader │ │ ├── DrawDepth.glsl │ │ ├── DrawDepthCube.glsl │ │ ├── DrawDepthLeagcy.glsl │ │ └── Lambert │ │ ├── GBuffer.glsl │ │ ├── GBufferNoTexture.glsl │ │ ├── Lambert.glsl │ │ ├── PointLight.glsl │ │ ├── SpotLight.glsl │ │ └── SunLight.glsl │ ├── demo.app │ └── Contents │ │ ├── Info.plist │ │ └── Resources │ │ └── demo.icns │ └── readme.txt └── screenshots ├── 1.jpg └── 2.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | /engine/build/ 2 | /engine/lib/ 3 | *.sublime-project 4 | *.sublime-workspace -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 sindney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.ZH-CN.md: -------------------------------------------------------------------------------- 1 | ![](https://img.shields.io/badge/dev-v0.2.1-green.svg) ![](https://img.shields.io/badge/build-passing-green.svg) ![](https://img.shields.io/badge/license-MIT-blue.svg) 2 | 3 | # Fury3D 4 | 5 | [English](README.md) 6 | 7 | ## 简介 8 | 9 | Fury3d是一个使用C++11与高版本opengl编写的跨平台3D引擎。 10 | 11 | 目前支持Windows与Mac OSX操作系统。 12 | 13 | 注意,此项目仅仅是个人学习用项目。 14 | 15 | 特性: 16 | 17 | * 使用现代的Opengl 18 | * C++11的智能指针简化了内存管理的复杂度 19 | * 灵活的Signal消息系统 (使用函数指针,所以不支持lambda函数) 20 | * 支持FBX模型文件的读取,可直接读取场景的灯光,静态模型,以及带有蒙皮骨骼动画的模型 21 | * 可使用json自由配置的渲染管线 22 | * 内置阉割版light-pre pass渲染管线 23 | * 接入了强大的GUI库[ImGui](https://github.com/ocornut/imgui) 24 | * 支持方向光,点光,聚光灯的阴影贴图 25 | * 拥有自己的场景文件,支持输出json,支持压缩解压缩 26 | 27 | 计划: 28 | 29 | * 添加阴影. (已实现,需改进) 30 | * 添加骨骼动画. (已简单实现,仍需改进) 31 | * 解析GLTF场景交换格式,放弃支持FbxSDK 32 | * 实现HDR管线与PBR材质 33 | 34 | ## 兼容性 35 | 36 | 测试编译器: 37 | 38 | * MSVC 2013 Community 39 | * Apple LLVM version 7.0.2 (clang-700.1.81) 40 | 41 | 由于FBX SDK在Windows系统上 (FBXSDK为可选编译选项,可通过引擎的场景文件载入场景),只有MSVC编译的版本,所以在Windows上必须用MSVC编译Fury3D。 42 | 43 | 应该支持所有支持Opengl3.3+的显卡 44 | 45 | 测试第三方库: 46 | 47 | * Rapidjson 1.1.0 48 | * SFML 2.4.1 49 | 50 | ## 测试截图 51 | 52 | ![阴影和动态光照](screenshots/1.jpg) 53 | 54 | ![阴影和动态光照](screenshots/2.jpg) 55 | 56 | ## 例子 57 | 58 | 你可以使用json配置自己的渲染管线,[去看看。](https://github.com/sindney/fury3d/blob/master/examples/bin/Resource/Pipeline/DefferedLighting.json) 59 | 60 | 一个最简单的例子: 61 | 62 | ~~~~~~~~~~cpp 63 | // 这是我们场景树的根节点 64 | auto m_RootNode = SceneNode::Create("Root"); 65 | 66 | // 可以从fbx文件载入场景 67 | FbxParser::Instance()->LoadScene("Resource/Scene/scene.fbx", m_RootNode, importOptions); 68 | 69 | // 也可以从fury的自定义场景文件中载入场景 70 | FileUtil::LoadCompressedFile(m_Scene, FileUtil::GetAbsPath("Resource/Scene/scene.bin")); 71 | 72 | // 你可以遍历任意一种载入的资源列表 73 | Scene::Manager()->ForEach([&](const AnimationClip::Ptr &clip) -> bool 74 | { 75 | std::cout << "Clip: " << clip->GetName() << " Duration: " << clip->GetDuration() << std::endl; 76 | return true; 77 | }); 78 | 79 | // 也可以通过名字或者名字的哈希值来得到某资源指针 80 | auto clip = Scene::Manager()->Get("James|Walk"); 81 | 82 | // 初始化八叉树 83 | auto m_OcTree = OcTree::Create(Vector4(-10000, -10000, -10000, 1), Vector4(10000, 10000, 10000, 1), 2); 84 | m_OcTree->AddSceneNodeRecursively(m_RootNode); 85 | 86 | // 载入渲染管线 87 | auto m_Pipeline = PrelightPipeline::Create("pipeline"); 88 | FileUtil::LoadFile(m_Pipeline, FileUtil::GetAbsPath("Path To Pipeline.json")); 89 | 90 | // 绘制场景 91 | m_Pipeline->Execute(m_OcTree); 92 | ~~~~~~~~~~ 93 | 94 | ## 非常感谢 95 | 96 | * [FbxSdk](http://www.autodesk.com/products/fbx/overview) - Fbx模型加载 97 | * [Rapidjson](https://github.com/miloyip/rapidjson) - Json的序列化反序列化 98 | * [Plog](https://github.com/SergiusTheBest/plog) - 日志的实现 99 | * [ThreadPool](https://github.com/progschj/ThreadPool) - 线程池的实现 100 | * [Stbimage](https://github.com/nothings/stb) - 载入图像 101 | * [LZ4](https://github.com/Cyan4973/lz4) - 文件压缩与解压缩 102 | * [Sfml](http://www.sfml-dev.org) - 解决平台相关的窗口相关需求 103 | * [ASSIMP](https://github.com/assimp/assimp) - Mesh的物理资源优化 104 | * [Ogre3d](http://www.ogre3d.org) - 八叉树的实现 105 | * [ImGui](https://github.com/ocornut/imgui) - 测试用GUI库 106 | * [RenderDoc](https://github.com/baldurk/renderdoc) - 测试Opengl渲染 107 | 108 | ## 最后 109 | 110 | 如果你使用SublimeText码字,可以尝试我的 [GLSLCompiler](https://github.com/sindney/GLSLCompiler) 组件来debug glsl代码 :D 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://img.shields.io/badge/dev-v0.2.1-green.svg) ![](https://img.shields.io/badge/build-passing-green.svg) ![](https://img.shields.io/badge/license-MIT-blue.svg) 2 | 3 | # Fury3D 4 | 5 | [中文简体](README.ZH-CN.md) 6 | 7 | ## Introduction 8 | 9 | Fury3d is a cross-platform rendering engine written in c++11 and modern opengl. 10 | 11 | Works on windows && osx operating systems currentlly. 12 | 13 | Please note, this is just a simple project for study purpose. 14 | 15 | Features: 16 | 17 | * Use modern opengl. 18 | * C++11 smart pointers made memory management easier. 19 | * Flexible signal message system. (use function pointers, so it won't accept lambdas, sry) 20 | * Support fbx model format, you can load static meshes, skinned meshes and lights directlly. 21 | * Easy rendering pipeline management through json serialization functionality. 22 | * Build-in light-pre pass rendering pipeling. 23 | * Intergates powerful gui library [ImGui](https://github.com/ocornut/imgui). 24 | * Support Shadow Mapping For Dir/Point/Spot Light. 25 | * Support custom scene format, can save to json and can be compressed. 26 | 27 | Plans: 28 | 29 | * Add shadow maps. (Done, need improvements) 30 | * Add skeleton animation support. (Done, but need improvements) 31 | * Implement GLTF file format parsing, dropping support for FbxSDK. 32 | * Implement HDR rendering pipeline, and support PBR material. 33 | 34 | ## Compatibility 35 | 36 | Tested compilers: 37 | 38 | * MSVC 2013 Community 39 | * Apple LLVM version 7.0.2 (clang-700.1.81) 40 | 41 | Because fbxsdk only offers MSVC builds on windows (FBXSDK is optional, you can load scene using engine's custom scene format), so you must use MSVC to build the library. 42 | 43 | Should work with any graphic card that supports opengl 3.3 + 44 | 45 | Tested libraries: 46 | * Rapidjson 1.1.0 47 | * SFML 2.4.1 48 | 49 | ## Screenshots 50 | 51 | ![Shadows](screenshots/1.jpg) 52 | 53 | ![PolyScene](screenshots/2.jpg) 54 | 55 | ## Examples 56 | 57 | You can setup custom rendering pipeline using json file, [check it out.](https://github.com/sindney/fury3d/blob/master/examples/bin/Resource/Pipeline/DefferedLighting.json) 58 | 59 | A simple demo should look like this: 60 | 61 | ~~~~~~~~~~cpp 62 | // This is the root of our scene 63 | auto m_RootNode = SceneNode::Create("Root"); 64 | 65 | // You can load scene from fbx file. 66 | FbxParser::Instance()->LoadScene("Resource/Scene/scene.fbx", m_RootNode, importOptions); 67 | 68 | // Or from fury's scene format. 69 | FileUtil::LoadCompressedFile(m_Scene, FileUtil::GetAbsPath("Resource/Scene/scene.bin")); 70 | 71 | // You can iterate a certain type of imported resources. 72 | Scene::Manager()->ForEach([&](const AnimationClip::Ptr &clip) -> bool 73 | { 74 | std::cout << "Clip: " << clip->GetName() << " Duration: " << clip->GetDuration() << std::endl; 75 | return true; 76 | }); 77 | 78 | // And you can simply find an resource by it's name or hashcode. 79 | auto clip = Scene::Manager()->Get("James|Walk"); 80 | 81 | // Setup octree 82 | auto m_OcTree = OcTree::Create(Vector4(-10000, -10000, -10000, 1), Vector4(10000, 10000, 10000, 1), 2); 83 | m_OcTree->AddSceneNodeRecursively(m_RootNode); 84 | 85 | // Load pipeline 86 | auto m_Pipeline = PrelightPipeline::Create("pipeline"); 87 | FileUtil::LoadFile(m_Pipeline, FileUtil::GetAbsPath("Path To Pipeline.json")); 88 | 89 | // Draw scene 90 | m_Pipeline->Execute(m_OcTree); 91 | ~~~~~~~~~~ 92 | 93 | ## Special thanks 94 | 95 | * [FbxSdk](http://www.autodesk.com/products/fbx/overview) - for loading fbx model 96 | * [Rapidjson](https://github.com/miloyip/rapidjson) - for loading pipeline setups 97 | * [Plog](https://github.com/SergiusTheBest/plog) - for log implimentation 98 | * [ThreadPool](https://github.com/progschj/ThreadPool) - for threadpool implimentation 99 | * [Stbimage](https://github.com/nothings/stb) - for image loading 100 | * [LZ4](https://github.com/Cyan4973/lz4) - for file compressing/decompressing 101 | * [Sfml](http://www.sfml-dev.org) - for os related window/input/context handling 102 | * [ASSIMP](https://github.com/assimp/assimp) - for mesh optimization 103 | * [Ogre3d](http://www.ogre3d.org) - for octree implimentation 104 | * [ImGui](https://github.com/ocornut/imgui) - for debuging gui 105 | * [RenderDoc](https://github.com/baldurk/renderdoc) - for debuging opengl 106 | 107 | ## One more thing 108 | 109 | If you use sublimetext, you can try my [GLSLCompiler](https://github.com/sindney/GLSLCompiler) plugin to debug glsl code :D 110 | -------------------------------------------------------------------------------- /engine/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | 3 | project(FURY3D) 4 | 5 | if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") 6 | set(OS_WINDOWS 1) 7 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 8 | set(OS_MACOSX 1) 9 | else() 10 | message(SEND_ERROR "Only support windows && osx currentlly.") 11 | endif() 12 | 13 | set(RAPIDJSON_INCLUDE "/usr/local/include" CACHE PATH "Path to rapidjson headers.") 14 | 15 | set(SFML_INCLUDE "/usr/local/include" CACHE PATH "Location of SFML headers.") 16 | set(SFML_LIB "/usr/local/lib" CACHE PATH "Location of SFML lib.") 17 | 18 | option(FBXPARSER_IMP "Use FbxParser." OFF) 19 | if(FBXPARSER_IMP) 20 | add_definitions(-D_FURY_FBXPARSER_IMP_) 21 | set(FBXSDK_INCLUDE "/usr/local/include" CACHE PATH "Path to fbxsdk headers.") 22 | set(FBXSDK_LIB_RELEASE "/usr/local/lib" CACHE FILEPATH "Path to fbxsdk release lib.") 23 | set(FBXSDK_LIB_DEBUG "/usr/local/lib" CACHE FILEPATH "Path to fbxsdk debug lib.") 24 | set(FBXSDK_LIB optimized ${FBXSDK_LIB_RELEASE} debug ${FBXSDK_LIB_DEBUG}) 25 | endif() 26 | 27 | option(GUI_IMP "Use ImGui." ON) 28 | if(GUI_IMP) 29 | add_definitions(-D_FURY_GUI_IMP_) 30 | endif() 31 | 32 | set(CMAKE_CXX_FLAGS "-std=c++11 -Wno-int-to-void-pointer-cast") 33 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") 34 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -O2 -NDEBUG") 35 | 36 | option(BUILD_SHARED_LIBS "Build shared librarie." ON) 37 | 38 | if(OS_WINDOWS) 39 | option(EXPORT_DLL "Define FURY_API_EXPORT" ON) 40 | if(EXPORT_DLL) 41 | add_definitions(-DFURY_API_EXPORT) 42 | endif() 43 | endif() 44 | 45 | # add_subdirectory(src) 46 | 47 | include_directories(${PROJECT_SOURCE_DIR}) 48 | 49 | include_directories(${RAPIDJSON_INCLUDE}) 50 | 51 | include_directories(${SFML_INCLUDE}) 52 | link_directories(${SFML_LIB}) 53 | 54 | include_directories(${PROJECT_SOURCE_DIR}/ThirdParty) 55 | 56 | include_directories(${PROJECT_SOURCE_DIR}/ThirdParty/STB) 57 | 58 | file(GLOB IMGUI_SRC ${PROJECT_SOURCE_DIR}/ThirdParty/ImGui/*.cpp) 59 | 60 | include_directories(${PROJECT_SOURCE_DIR}/ThirdParty/LZ4) 61 | file(GLOB LZ4_SRC ${PROJECT_SOURCE_DIR}/ThirdParty/LZ4/*.c) 62 | 63 | if(FBXPARSER_IMP) 64 | include_directories(${FBXSDK_INCLUDE}) 65 | endif() 66 | 67 | if(OS_MACOSX) 68 | find_library(COREFOUNDATION_LIB CoreFoundation) 69 | find_package(OpenGL REQUIRED) 70 | include_directories(${OPENGL_INCLUDE_DIR}) 71 | endif() 72 | 73 | file(GLOB FURY_SRC ${PROJECT_SOURCE_DIR}/Fury/*.cpp) 74 | list(APPEND FURY_SRC ${IMGUI_SRC} ${LZ4_SRC}) 75 | 76 | if(BUILD_SHARED_LIBS) 77 | add_library(fury SHARED ${FURY_SRC}) 78 | if(OS_WINDOWS) 79 | target_link_libraries(fury sfml-window sfml-system opengl32 ${FBXSDK_LIB}) 80 | elseif(OS_MACOSX) 81 | target_link_libraries(fury sfml-window sfml-system ${OPENGL_LIBRARIES} ${COREFOUNDATION_LIB} ${FBXSDK_LIB}) 82 | set_target_properties(fury PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@executable_path") 83 | endif() 84 | else() 85 | add_library(fury STATIC ${FURY_SRC}) 86 | endif() 87 | 88 | install(TARGETS fury DESTINATION lib) -------------------------------------------------------------------------------- /engine/Fury/AnimationClip.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/AnimationClip.h" 2 | #include "Fury/Log.h" 3 | 4 | namespace fury 5 | { 6 | AnimationClip::Ptr AnimationClip::Create(const std::string &name, int ticksPerSecond) 7 | { 8 | return std::make_shared(name, ticksPerSecond); 9 | } 10 | 11 | AnimationClip::AnimationClip(const std::string &name, int ticksPerSecond) 12 | : Entity(name), m_TicksPerSecond(ticksPerSecond) 13 | { 14 | m_TypeIndex = typeid(AnimationClip); 15 | } 16 | 17 | AnimationClip::~AnimationClip() 18 | { 19 | FURYD << "AnimationClip " << m_Name << " destoried!"; 20 | } 21 | 22 | void AnimationClip::CalculateDuration() 23 | { 24 | m_Duration = 0.0f; 25 | 26 | auto Try = [&](unsigned int value) 27 | { 28 | float time = (float)value / m_TicksPerSecond; 29 | if (time > m_Duration) 30 | m_Duration = time; 31 | }; 32 | 33 | for (auto channel : m_Channels) 34 | { 35 | int posCount = channel->positions.size(); 36 | if (posCount > 0) 37 | Try(channel->positions[posCount - 1].tick); 38 | 39 | int rotCount = channel->rotations.size(); 40 | if (rotCount > 0) 41 | Try(channel->rotations[rotCount - 1].tick); 42 | 43 | int sclCount = channel->scalings.size(); 44 | if (sclCount > 0) 45 | Try(channel->scalings[sclCount - 1].tick); 46 | } 47 | } 48 | 49 | float AnimationClip::GetDuration() const 50 | { 51 | return m_Duration; 52 | } 53 | 54 | void AnimationClip::SetDuration(float duration) 55 | { 56 | m_Duration = duration; 57 | } 58 | 59 | float AnimationClip::GetSpeed() const 60 | { 61 | return m_Speed; 62 | } 63 | 64 | void AnimationClip::SetSpeed(float speed) 65 | { 66 | m_Speed = speed; 67 | } 68 | 69 | int AnimationClip::GetTicksPerSecond() const 70 | { 71 | return m_TicksPerSecond; 72 | } 73 | 74 | void AnimationClip::SetTicksPerSecond(int ticksPerSecond) 75 | { 76 | if (m_TicksPerSecond != ticksPerSecond) 77 | { 78 | m_TicksPerSecond = ticksPerSecond; 79 | CalculateDuration(); 80 | } 81 | } 82 | 83 | bool AnimationClip::GetLoop() const 84 | { 85 | return m_Loop; 86 | } 87 | 88 | void AnimationClip::SetLoop(bool loop) 89 | { 90 | m_Loop = loop; 91 | } 92 | 93 | int AnimationClip::GetChannelCount() const 94 | { 95 | return m_Channels.size(); 96 | } 97 | 98 | AnimationClip::ChannelPtr AnimationClip::AddChannel(const std::string &name) 99 | { 100 | auto channel = std::make_shared(name); 101 | m_Channels.push_back(channel); 102 | return channel; 103 | } 104 | 105 | void AnimationClip::AddChannel(const AnimationClip::ChannelPtr &channel) 106 | { 107 | m_Channels.push_back(channel); 108 | } 109 | 110 | AnimationClip::ChannelPtr AnimationClip::RemoveChannel(const std::string &name) 111 | { 112 | for (unsigned int i = 0; i < m_Channels.size(); i++) 113 | { 114 | auto channel = m_Channels[i]; 115 | if (channel->name == name) 116 | { 117 | m_Channels.erase(m_Channels.begin() + i); 118 | return channel; 119 | } 120 | } 121 | return nullptr; 122 | } 123 | 124 | AnimationClip::ChannelPtr AnimationClip::GetChannel(const std::string &name) const 125 | { 126 | for (unsigned int i = 0; i < m_Channels.size(); i++) 127 | { 128 | auto channel = m_Channels[i]; 129 | if (channel->name == name) 130 | return channel; 131 | } 132 | return nullptr; 133 | } 134 | 135 | AnimationClip::ChannelPtr AnimationClip::GetChannelAt(unsigned int index) const 136 | { 137 | if (index < m_Channels.size()) 138 | return m_Channels[index]; 139 | else 140 | return nullptr; 141 | } 142 | } -------------------------------------------------------------------------------- /engine/Fury/AnimationClip.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_ANIMATION_CLIP_H_ 2 | #define _FURY_ANIMATION_CLIP_H_ 3 | 4 | #include 5 | 6 | #include "Fury/Entity.h" 7 | 8 | namespace fury 9 | { 10 | struct KeyFrame 11 | { 12 | public: 13 | 14 | unsigned int tick; 15 | 16 | float x, y, z; 17 | 18 | KeyFrame(unsigned int tick = 0, float x = 0.0f, float y = 0.0f, float z = 0.0f) : 19 | tick(tick), x(x), y(y), z(z) {} 20 | }; 21 | 22 | struct AnimationChannel 23 | { 24 | public: 25 | 26 | std::vector rotations; 27 | 28 | std::vector positions; 29 | 30 | std::vector scalings; 31 | 32 | std::string name; 33 | 34 | AnimationChannel(const std::string &name) : 35 | name(name) {} 36 | }; 37 | 38 | class FURY_API AnimationClip final : public Entity 39 | { 40 | public: 41 | 42 | friend class AnimationUtil; 43 | 44 | typedef std::shared_ptr Ptr; 45 | 46 | typedef std::shared_ptr ChannelPtr; 47 | 48 | static Ptr Create(const std::string &name, int ticksPerSecond = 24); 49 | 50 | private: 51 | 52 | std::vector> m_Channels; 53 | 54 | float m_Duration = 0.0f; 55 | 56 | float m_Speed = 1.0f; 57 | 58 | int m_TicksPerSecond = 24; 59 | 60 | bool m_Loop = true; 61 | 62 | public: 63 | 64 | AnimationClip(const std::string &name, int ticksPerSecond = 24); 65 | 66 | virtual ~AnimationClip(); 67 | 68 | void CalculateDuration(); 69 | 70 | float GetDuration() const; 71 | 72 | void SetDuration(float duration); 73 | 74 | float GetSpeed() const; 75 | 76 | void SetSpeed(float speed); 77 | 78 | int GetTicksPerSecond() const; 79 | 80 | void SetTicksPerSecond(int ticksPerSecond); 81 | 82 | bool GetLoop() const; 83 | 84 | void SetLoop(bool loop); 85 | 86 | int GetChannelCount() const; 87 | 88 | ChannelPtr AddChannel(const std::string &name); 89 | 90 | void AddChannel(const ChannelPtr &channel); 91 | 92 | ChannelPtr RemoveChannel(const std::string &name); 93 | 94 | ChannelPtr GetChannel(const std::string &name) const; 95 | 96 | ChannelPtr GetChannelAt(unsigned int index) const; 97 | }; 98 | 99 | } 100 | 101 | #endif // _FURY_ANIMATION_CLIP_H_ -------------------------------------------------------------------------------- /engine/Fury/AnimationPlayer.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_ANIMATION_PLAYER_H_ 2 | #define _FURY_ANIMATION_PLAYER_H_ 3 | 4 | #include "Fury/Entity.h" 5 | 6 | namespace fury 7 | { 8 | class AnimationClip; 9 | 10 | class SceneNode; 11 | 12 | class FURY_API AnimationPlayer : public Entity 13 | { 14 | public: 15 | 16 | typedef std::shared_ptr Ptr; 17 | 18 | static Ptr Create(const std::string &name, float speed = 1.0f); 19 | 20 | protected: 21 | 22 | std::weak_ptr m_SceneNode; 23 | 24 | std::weak_ptr m_AnimClip; 25 | 26 | float m_Speed = 1.0f; 27 | 28 | float m_Time = 0.0f; 29 | 30 | public: 31 | 32 | AnimationPlayer(const std::string &name, float speed = 1.0f); 33 | 34 | void SetSpeed(float speed); 35 | 36 | float GetSpeed() const; 37 | 38 | void SetTime(float time); 39 | 40 | float GetTime() const; 41 | 42 | // make sure the node has meshRender compnent with a mesh. 43 | void AdvanceTime(const std::shared_ptr &node, const std::shared_ptr &clip, float dt); 44 | 45 | void AdvanceTime(const std::shared_ptr &clip, float dt); 46 | 47 | void AdvanceTime(float dt); 48 | 49 | // 0 - 1, this interpolates the result from advanceTime call. 50 | void Display(float dt); 51 | }; 52 | } 53 | 54 | #endif // _FURY_ANIMATION_PLAYER_H_ -------------------------------------------------------------------------------- /engine/Fury/AnimationUtil.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "Fury/MathUtil.h" 4 | #include "Fury/AnimationClip.h" 5 | #include "Fury/AnimationUtil.h" 6 | #include "Fury/Log.h" 7 | 8 | namespace fury 9 | { 10 | void AnimationUtil::OptimizeAnimClip(const std::shared_ptr &clip, float quality) 11 | { 12 | if (quality > 1.0f) 13 | quality = 1.0f; 14 | 15 | float maxAngle = quality * MathUtil::DegreeToRadian(45); 16 | std::vector tempFrames; 17 | 18 | auto ProcessKeyFrames = [&](std::vector &keyframes) 19 | { 20 | unsigned int count = keyframes.size(); 21 | if (count < 3) 22 | return; 23 | 24 | KeyFrame prev = keyframes[0]; 25 | tempFrames.erase(tempFrames.begin(), tempFrames.end()); 26 | tempFrames.reserve(count); 27 | tempFrames.push_back(prev); 28 | 29 | for (unsigned int i = 1; i < count - 1; i++) 30 | { 31 | KeyFrame curr = keyframes[i], next = keyframes[i + 1]; 32 | 33 | Vector4 vec1(prev.x, prev.y, prev.z); 34 | Vector4 vec2(curr.x, curr.y, curr.z); 35 | Vector4 vec3(next.x, next.y, next.z); 36 | 37 | Vector4 a = (vec2 - vec1).Normalized(); 38 | if (a.SquareLength() == 0.0f) 39 | continue; 40 | 41 | Vector4 b = (vec3 - vec2).Normalized(); 42 | float angle = std::abs(std::acos(a * b)); 43 | 44 | if (angle < maxAngle) 45 | continue; 46 | 47 | prev = curr; 48 | tempFrames.push_back(curr); 49 | } 50 | 51 | tempFrames.push_back(keyframes[count - 1]); 52 | 53 | keyframes.resize(tempFrames.size()); 54 | std::copy(tempFrames.begin(), tempFrames.end(), keyframes.begin()); 55 | }; 56 | 57 | unsigned int oldCount = 0, newCount = 0; 58 | for (auto channel : clip->m_Channels) 59 | { 60 | if (channel->rotations.size() > 0) 61 | { 62 | oldCount += channel->rotations.size(); 63 | ProcessKeyFrames(channel->rotations); 64 | newCount += channel->rotations.size(); 65 | } 66 | 67 | if (channel->positions.size() > 0) 68 | { 69 | oldCount += channel->positions.size(); 70 | ProcessKeyFrames(channel->positions); 71 | newCount += channel->positions.size(); 72 | } 73 | 74 | if (channel->scalings.size() > 0) 75 | { 76 | oldCount += channel->scalings.size(); 77 | ProcessKeyFrames(channel->scalings); 78 | newCount += channel->scalings.size(); 79 | } 80 | } 81 | 82 | FURYD << "Before: " << oldCount << " After: " << newCount; 83 | } 84 | } -------------------------------------------------------------------------------- /engine/Fury/AnimationUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_ANIMATION_UTIL_H_ 2 | #define _FURY_ANIMATION_UTIL_H_ 3 | 4 | #include 5 | 6 | #include "Macros.h" 7 | 8 | namespace fury 9 | { 10 | class AnimationClip; 11 | 12 | class FURY_API AnimationUtil final 13 | { 14 | public: 15 | 16 | static void OptimizeAnimClip(const std::shared_ptr &clip, float quality = 0.5f); 17 | }; 18 | } 19 | 20 | #endif // _FURY_ANIMATION_UTIL_H_ -------------------------------------------------------------------------------- /engine/Fury/ArrayBuffers.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/ArrayBuffers.h" 2 | #include "Fury/Log.h" 3 | #include "Fury/GLLoader.h" 4 | 5 | namespace fury 6 | { 7 | template 8 | ArrayBuffer::ArrayBuffer(const std::string &name, unsigned int bufferTarget, unsigned int bufferUsage) 9 | : m_ID(0), m_SizeOld(0), Name(name), 10 | m_BufferTarget(bufferTarget), m_BufferUsage(bufferUsage), 11 | m_TypeIndex(typeid(ArrayBuffer)) 12 | { 13 | 14 | } 15 | 16 | template 17 | ArrayBuffer::~ArrayBuffer() 18 | { 19 | DeleteBuffer(); 20 | } 21 | 22 | template 23 | std::type_index ArrayBuffer::GetTypeIndex() const 24 | { 25 | return m_TypeIndex; 26 | } 27 | 28 | template 29 | void ArrayBuffer::UpdateBuffer() 30 | { 31 | int sizeNew = Data.size(); 32 | bool sizeChanged = false; 33 | bool isNewBuffer = false; 34 | 35 | if (sizeNew != m_SizeOld) 36 | { 37 | m_SizeOld = sizeNew; 38 | sizeChanged = true; 39 | } 40 | 41 | if (m_Dirty && sizeNew > 0) 42 | { 43 | m_Dirty = false; 44 | 45 | if (m_ID == 0) 46 | { 47 | glGenBuffers(1, &m_ID); 48 | isNewBuffer = true; 49 | } 50 | 51 | glBindBuffer(m_BufferTarget, m_ID); 52 | 53 | if (sizeChanged || isNewBuffer) 54 | glBufferData(m_BufferTarget, sizeNew * sizeof(DataType), Data.data(), m_BufferUsage); 55 | else 56 | glBufferSubData(m_BufferTarget, 0, sizeNew * sizeof(DataType), Data.data()); 57 | 58 | glBindBuffer(m_BufferTarget, 0); 59 | } 60 | } 61 | 62 | template 63 | void ArrayBuffer::DeleteBuffer() 64 | { 65 | m_Dirty = true; 66 | 67 | if (m_ID != 0) 68 | glDeleteBuffers(1, &m_ID); 69 | m_ID = 0; 70 | } 71 | 72 | template 73 | unsigned int ArrayBuffer::GetID() const 74 | { 75 | return m_ID; 76 | } 77 | 78 | template 79 | void ArrayBuffer::SetBufferUsage(unsigned int usage) 80 | { 81 | if (m_BufferUsage != usage) 82 | { 83 | DeleteBuffer(); 84 | UpdateBuffer(); 85 | } 86 | } 87 | 88 | template class ArrayBuffer; 89 | 90 | template class ArrayBuffer; 91 | 92 | template class ArrayBuffer; 93 | } -------------------------------------------------------------------------------- /engine/Fury/ArrayBuffers.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_ARRAYBUFFERS_H_ 2 | #define _FURY_ARRAYBUFFERS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Buffer.h" 8 | #include "Fury/Signal.h" 9 | #include "Fury/TypeComparable.h" 10 | 11 | namespace fury 12 | { 13 | template 14 | class FURY_API ArrayBuffer : public Buffer, public TypeComparable 15 | { 16 | protected: 17 | 18 | std::type_index m_TypeIndex; 19 | 20 | unsigned int m_ID; 21 | 22 | unsigned int m_SizeOld; 23 | 24 | unsigned int m_BufferTarget; 25 | 26 | unsigned int m_BufferUsage; 27 | 28 | public: 29 | 30 | std::string Name; 31 | 32 | std::vector Data; 33 | 34 | ArrayBuffer(const std::string &name, unsigned int bufferTarget, unsigned int bufferUsage); 35 | 36 | virtual std::type_index GetTypeIndex() const; 37 | 38 | virtual ~ArrayBuffer(); 39 | 40 | void UpdateBuffer(); 41 | 42 | virtual void DeleteBuffer(); 43 | 44 | unsigned int GetID() const; 45 | 46 | void SetBufferUsage(unsigned int usage); 47 | }; 48 | 49 | typedef ArrayBuffer ArrayBufferf; 50 | 51 | typedef ArrayBuffer ArrayBufferi; 52 | 53 | typedef ArrayBuffer ArrayBufferui; 54 | } 55 | 56 | #endif // _FURY_ARRAYBUFFERS_H_ -------------------------------------------------------------------------------- /engine/Fury/BoxBounds.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_BOXBOUNDS_H_ 2 | #define _FURY_BOXBOUNDS_H_ 3 | 4 | #include 5 | 6 | #include "Fury/Collidable.h" 7 | #include "Fury/Vector4.h" 8 | 9 | namespace fury 10 | { 11 | class SphereBounds; 12 | 13 | // axis aligned bounding box 14 | class FURY_API BoxBounds : public Collidable 15 | { 16 | protected: 17 | 18 | Vector4 m_Max, m_Min; 19 | 20 | Vector4 m_Extents, m_Size; 21 | 22 | Vector4 m_Center; 23 | 24 | bool m_Infinite = false; 25 | 26 | bool m_Dirty = false; 27 | 28 | public: 29 | 30 | BoxBounds(bool dirty = false); 31 | 32 | BoxBounds(Vector4 min, Vector4 max); 33 | 34 | void SetMinMax(Vector4 min, Vector4 max); 35 | 36 | void Zero(bool dirty = false); 37 | 38 | void SetInfinite(bool value); 39 | 40 | bool GetInfinite() const; 41 | 42 | virtual Side IsInside(Vector4 point) const; 43 | 44 | virtual Side IsInside(const SphereBounds &bsphere) const; 45 | 46 | virtual Side IsInside(const BoxBounds &aabb) const; 47 | 48 | virtual bool IsInsideFast(Vector4 point) const; 49 | 50 | virtual bool IsInsideFast(const BoxBounds &aabb) const; 51 | 52 | virtual bool IsInsideFast(const SphereBounds &bsphere) const; 53 | 54 | // grow to include another aabb. 55 | void Encapsulate(const BoxBounds &aabb); 56 | 57 | // grow to include another bsphere. 58 | void Encapsulate(const SphereBounds &bsphere); 59 | 60 | // grow to include a point. 61 | void Encapsulate(Vector4 point); 62 | 63 | // the closest point on the aabb. 64 | // if the point is inside the aabb, unmodified point will be returned. 65 | Vector4 ClosestPoint(Vector4 point) const; 66 | 67 | // the farest point on the aabb. 68 | // if the point is inside the aabb, unmodified point will be returned. 69 | Vector4 FarestPoint(Vector4 point) const; 70 | 71 | // get the shortest distance between point to aabb. 72 | // if the point is inside the aabb, 0 will be returned. 73 | float GetDistance(Vector4 point) const; 74 | 75 | // get the positive vertex to a plane. 76 | Vector4 GetVertexP(Vector4 normal) const; 77 | 78 | // get the negative vertex to a plane. 79 | Vector4 GetVertexN(Vector4 normal) const; 80 | 81 | Vector4 GetCenter() const; 82 | 83 | Vector4 GetExtents() const; 84 | 85 | Vector4 GetMax() const; 86 | 87 | Vector4 GetMin() const; 88 | 89 | Vector4 GetSize() const; 90 | 91 | std::array GetCorners() const; 92 | 93 | bool Valid() const; 94 | 95 | bool GetDirty() const; 96 | 97 | // this will change Encapsulate's first-time behaviour. 98 | void SetDirty(bool dirty); 99 | 100 | BoxBounds &operator = (const BoxBounds &data); 101 | 102 | bool operator == (const BoxBounds &data) const; 103 | 104 | bool operator != (const BoxBounds &data) const; 105 | 106 | }; 107 | } 108 | 109 | #endif // _FURY_BOXBOUNDS_H_ -------------------------------------------------------------------------------- /engine/Fury/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/Buffer.h" 2 | 3 | namespace fury 4 | { 5 | size_t Buffer::m_CurBufferId = 0; 6 | 7 | void Buffer::SetDirty() 8 | { 9 | m_Dirty = true; 10 | } 11 | 12 | bool Buffer::GetDirty() const 13 | { 14 | return m_Dirty; 15 | } 16 | 17 | size_t Buffer::GetBufferId() const 18 | { 19 | return m_BufferId; 20 | } 21 | } -------------------------------------------------------------------------------- /engine/Fury/Buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_BUFFER_H_ 2 | #define _FURY_BUFFER_H_ 3 | 4 | #include 5 | 6 | #include "Macros.h" 7 | 8 | namespace fury 9 | { 10 | class FURY_API Buffer 11 | { 12 | public: 13 | 14 | typedef std::shared_ptr Ptr; 15 | 16 | protected: 17 | 18 | static size_t m_CurBufferId; 19 | 20 | bool m_Dirty = true; 21 | 22 | size_t m_BufferId = m_CurBufferId++; 23 | 24 | public: 25 | 26 | virtual void UpdateBuffer() = 0; 27 | 28 | virtual void DeleteBuffer() = 0; 29 | 30 | void SetDirty(); 31 | 32 | bool GetDirty() const; 33 | 34 | size_t GetBufferId() const; 35 | }; 36 | } 37 | 38 | #endif // _FURY_BUFFER_H_ -------------------------------------------------------------------------------- /engine/Fury/BufferManager.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/BufferManager.h" 2 | 3 | namespace fury 4 | { 5 | void BufferManager::Remove(size_t id) 6 | { 7 | auto it = m_Buffers.find(id); 8 | if (it != m_Buffers.end()) 9 | m_Buffers.erase(it); 10 | } 11 | 12 | void BufferManager::Release(size_t id) 13 | { 14 | auto it = m_Buffers.find(id); 15 | if (it != m_Buffers.end()) 16 | { 17 | if (!it->second.expired()) 18 | it->second.lock()->DeleteBuffer(); 19 | 20 | m_Buffers.erase(it); 21 | } 22 | } 23 | 24 | void BufferManager::RemoveAll() 25 | { 26 | m_Buffers.clear(); 27 | } 28 | 29 | void BufferManager::ReleaseAll() 30 | { 31 | for (auto pair : m_Buffers) 32 | { 33 | if (!pair.second.expired()) 34 | pair.second.lock()->DeleteBuffer(); 35 | } 36 | 37 | m_Buffers.clear(); 38 | } 39 | 40 | void BufferManager::IncreaseMemory(unsigned int byte, bool gpu) 41 | { 42 | if (gpu) 43 | m_GPUMemories += byte; 44 | else 45 | m_CPUMemories += byte; 46 | } 47 | 48 | void BufferManager::DecreaseMemory(unsigned int byte, bool gpu) 49 | { 50 | if (gpu) 51 | m_GPUMemories -= byte; 52 | else 53 | m_CPUMemories -= byte; 54 | } 55 | 56 | unsigned int BufferManager::GetMemoryInMegaByte(bool gpu) 57 | { 58 | if (gpu) 59 | return m_GPUMemories / 1000000; 60 | else 61 | return m_CPUMemories / 1000000; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /engine/Fury/BufferManager.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_BUFFER_MANAGER_H_ 2 | #define _FURY_BUFFER_MANAGER_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Buffer.h" 8 | #include "Fury/Signal.h" 9 | #include "Fury/Singleton.h" 10 | 11 | namespace fury 12 | { 13 | class FURY_API BufferManager final : public Singleton 14 | { 15 | public: 16 | 17 | typedef std::shared_ptr Ptr; 18 | 19 | private: 20 | 21 | std::unordered_map> m_Buffers; 22 | 23 | // in byte 24 | unsigned int m_CPUMemories = 0; 25 | 26 | // in byte 27 | unsigned int m_GPUMemories = 0; 28 | 29 | public: 30 | 31 | template 32 | bool Add(const std::shared_ptr &buffer) 33 | { 34 | static_assert(std::is_base_of::value, "BufferType should extend Buffer Class"); 35 | 36 | auto it = m_Buffers.find(buffer->GetBufferId()); 37 | if (it != m_Buffers.end()) 38 | { 39 | m_Buffers.emplace(buffer->GetBufferId(), std::static_pointer_cast(buffer)); 40 | return true; 41 | } 42 | else 43 | { 44 | return false; 45 | } 46 | } 47 | 48 | // stop tracking buffer 49 | void Remove(size_t id); 50 | 51 | // stop tracking and release memories 52 | void Release(size_t id); 53 | 54 | void RemoveAll(); 55 | 56 | void ReleaseAll(); 57 | 58 | void IncreaseMemory(unsigned int byte, bool gpu = true); 59 | 60 | void DecreaseMemory(unsigned int byte, bool gpu = true); 61 | 62 | unsigned int GetMemoryInMegaByte(bool gpu = true); 63 | }; 64 | } 65 | 66 | #endif // _FURY_BUFFER_MANAGER_H_ -------------------------------------------------------------------------------- /engine/Fury/Camera.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_CAMERA_H_ 2 | #define _FURY_CAMERA_H_ 3 | 4 | #include 5 | 6 | #include "Fury/BoxBounds.h" 7 | #include "Fury/Component.h" 8 | #include "Fury/Matrix4.h" 9 | #include "Fury/Frustum.h" 10 | 11 | namespace fury 12 | { 13 | class SceneNode; 14 | 15 | class FURY_API Camera : public Component, public std::enable_shared_from_this 16 | { 17 | protected: 18 | 19 | Matrix4 m_ProjectionMatrix; 20 | 21 | Frustum m_Frustum; 22 | 23 | BoxBounds m_ShadowAABB; 24 | 25 | bool m_Perspective = true; 26 | 27 | // left, right, bottom, top, near, far 28 | std::array m_ProjectionParams; 29 | 30 | float m_ShadowFar = 0.0f; 31 | 32 | size_t m_SignalKey = 0; 33 | 34 | public: 35 | 36 | typedef std::shared_ptr Ptr; 37 | 38 | static Ptr Create(); 39 | 40 | Camera(); 41 | 42 | Component::Ptr Clone() const override; 43 | 44 | void PerspectiveFov(float fov, float ratio, float near, float far); 45 | 46 | void PerspectiveOffCenter(float left, float right, float bottom, float top, float near, float far); 47 | 48 | void OrthoOffCenter(float left, float right, float bottom, float top, float near, float far); 49 | 50 | Matrix4 GetProjectionMatrix() const; 51 | 52 | Matrix4 GetProjectionMatrix(float near, float far) const; 53 | 54 | Frustum GetFrustum() const; 55 | 56 | Frustum GetFrustum(float near, float far) const; 57 | 58 | float GetNear() const; 59 | 60 | float GetFar() const; 61 | 62 | float GetShadowFar() const; 63 | 64 | void SetShadowFar(float far); 65 | 66 | BoxBounds GetShadowBounds(bool worldSpace = true) const; 67 | 68 | void SetShadowBounds(Vector4 min, Vector4 max); 69 | 70 | bool IsPerspective() const; 71 | 72 | // transform camera's frustum to match camera's current matrix. 73 | void Transform(const Matrix4 &matrix); 74 | 75 | // test the visiablity of an aabb. 76 | bool IsVisible(const BoxBounds &aabb) const; 77 | 78 | // test the visiablity of an bsphere. 79 | bool IsVisible(const SphereBounds &bsphere) const; 80 | 81 | // test the visiablity of a point. 82 | bool IsVisible(Vector4 point) const; 83 | 84 | // SceneNode::OnTransformChange callback. 85 | void OnSceneNodeTransformChange(const std::shared_ptr &sender); 86 | 87 | protected: 88 | 89 | virtual void OnAttaching(const std::shared_ptr &node) override; 90 | 91 | virtual void OnDetaching(const std::shared_ptr &node) override; 92 | }; 93 | } 94 | 95 | #endif // _FURY_CAMERA_H_ 96 | -------------------------------------------------------------------------------- /engine/Fury/Collidable.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_COLLIDABLE_H_ 2 | #define _FURY_COLLIDABLE_H_ 3 | 4 | #include "Fury/Plane.h" 5 | 6 | namespace fury 7 | { 8 | class BoxBounds; 9 | 10 | class SphereBounds; 11 | 12 | class Vector4; 13 | 14 | class FURY_API Collidable 15 | { 16 | public: 17 | 18 | virtual Side IsInside(Vector4 point) const = 0; 19 | 20 | virtual Side IsInside(const BoxBounds &aabb) const = 0; 21 | 22 | virtual Side IsInside(const SphereBounds &bsphere) const = 0; 23 | 24 | virtual bool IsInsideFast(const SphereBounds &bsphere) const = 0; 25 | 26 | virtual bool IsInsideFast(const BoxBounds &aabb) const = 0; 27 | 28 | virtual bool IsInsideFast(Vector4 point) const = 0; 29 | }; 30 | } 31 | 32 | #endif // _FURY_COLLIDABLE_H_ -------------------------------------------------------------------------------- /engine/Fury/Color.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/Color.h" 2 | 3 | namespace fury 4 | { 5 | Color Color::Black = Color(0, 0, 0); 6 | 7 | Color Color::Blue = Color(0, 0, 1); 8 | 9 | Color Color::Cyan = Color(0, 1, 1); 10 | 11 | Color Color::Gray = Color(0.5f, 0.5f, 0.5f); 12 | 13 | Color Color::Green = Color(0, 1, 0); 14 | 15 | Color Color::Magenta = Color(1, 0, 1); 16 | 17 | Color Color::Red = Color(1, 0, 0); 18 | 19 | Color Color::White = Color(1, 1, 1); 20 | 21 | Color Color::Yellow = Color(1, 1, 0); 22 | 23 | Color Color::Lerp(Color color, float t) const 24 | { 25 | float it = 1.0f - t; 26 | return Color( 27 | r * it + color.r * t, 28 | g * it + color.g * t, 29 | b * it + color.b * t 30 | ); 31 | } 32 | 33 | Color Color::Invert() const 34 | { 35 | return Color(1.0f - r, 1.0f - g, 1.0f - b); 36 | } 37 | 38 | Color &Color::operator = (Color other) 39 | { 40 | r = other.r; 41 | b = other.b; 42 | g = other.g; 43 | a = other.a; 44 | return *this; 45 | } 46 | 47 | bool Color::operator == (Color other) const 48 | { 49 | return r == other.r && g == other.g && b == other.b && a == other.a; 50 | } 51 | 52 | bool Color::operator != (Color other) const 53 | { 54 | return r != other.r || g != other.g || b != other.b || a != other.a; 55 | } 56 | } -------------------------------------------------------------------------------- /engine/Fury/Color.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_COLOR_H_ 2 | #define _FURY_COLOR_H_ 3 | 4 | #include "Macros.h" 5 | 6 | namespace fury 7 | { 8 | class FURY_API Color 9 | { 10 | public: 11 | 12 | static Color Black; 13 | 14 | static Color Blue; 15 | 16 | static Color Cyan; 17 | 18 | static Color Gray; 19 | 20 | static Color Green; 21 | 22 | static Color Magenta; 23 | 24 | static Color Red; 25 | 26 | static Color White; 27 | 28 | static Color Yellow; 29 | 30 | float r, g, b, a; 31 | 32 | Color(float r, float g, float b, float a = 1.0f) : r(r), g(g), b(b), a(a) {} 33 | 34 | Color Lerp(Color color, float t) const; 35 | 36 | Color Invert() const; 37 | 38 | Color &operator = (Color other); 39 | 40 | bool operator == (Color other) const; 41 | 42 | bool operator != (Color other) const; 43 | 44 | }; 45 | } 46 | 47 | #endif // _FURY_COLOR_H_ -------------------------------------------------------------------------------- /engine/Fury/Component.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/Component.h" 2 | #include "Fury/SceneNode.h" 3 | 4 | namespace fury 5 | { 6 | Component::Component() : m_TypeIndex(typeid(Component)) {} 7 | 8 | Component::~Component() 9 | { 10 | if (m_Owner.expired()) return; 11 | 12 | auto ptr = m_Owner.lock(); 13 | ptr->RemoveComponent(m_TypeIndex); 14 | } 15 | 16 | std::type_index Component::GetTypeIndex() const 17 | { 18 | return m_TypeIndex; 19 | } 20 | 21 | bool Component::HasOwner() const 22 | { 23 | return !m_Owner.expired(); 24 | } 25 | 26 | void Component::OnAttaching(const std::shared_ptr &node) 27 | { 28 | if (m_Owner.expired()) 29 | m_Owner = node; 30 | } 31 | 32 | void Component::OnDetaching(const std::shared_ptr &node) 33 | { 34 | m_Owner.reset(); 35 | } 36 | 37 | void Component::OnOwnerDestructing(SceneNode &node) 38 | { 39 | m_Owner.reset(); 40 | } 41 | } -------------------------------------------------------------------------------- /engine/Fury/Component.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_COMPONENT_H_ 2 | #define _FURY_COMPONENT_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/TypeComparable.h" 8 | #include "Fury/Serializable.h" 9 | 10 | namespace fury 11 | { 12 | class SceneNode; 13 | 14 | class FURY_API Component : public TypeComparable, public Serializable 15 | { 16 | friend class SceneNode; 17 | 18 | public: 19 | 20 | typedef std::shared_ptr Ptr; 21 | 22 | Component(); 23 | 24 | virtual ~Component(); 25 | 26 | virtual std::type_index GetTypeIndex() const; 27 | 28 | virtual Ptr Clone() const = 0; 29 | 30 | virtual bool Load(const void* wrapper, bool object = true) 31 | { 32 | return true; 33 | } 34 | 35 | virtual void Save(void* wrapper, bool object = true) {} 36 | 37 | bool HasOwner() const; 38 | 39 | protected: 40 | 41 | std::type_index m_TypeIndex; 42 | 43 | std::weak_ptr m_Owner; 44 | 45 | virtual void OnAttaching(const std::shared_ptr &node); 46 | 47 | virtual void OnDetaching(const std::shared_ptr &node); 48 | 49 | // this is called form owner's destructor. 50 | // so don't do nasty thing in it. 51 | virtual void OnOwnerDestructing(SceneNode &node); 52 | }; 53 | } 54 | 55 | #endif // _FURY_COMPONENT_H_ -------------------------------------------------------------------------------- /engine/Fury/Engine.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_ENGINE_H_ 2 | #define _FURY_ENGINE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "Fury/Log.h" 12 | #include "Fury/Signal.h" 13 | 14 | namespace fury 15 | { 16 | class FURY_API Engine 17 | { 18 | public: 19 | 20 | static bool Initialize(sf::Window &window, float guiScale, int numThreads, 21 | LogLevel level = LogLevel::EROR, const char* logfile = nullptr, 22 | bool console = true, const LogFormatter &formatter = Formatter::Simple, bool append = false); 23 | 24 | static void HandleEvent(sf::Event &event); 25 | 26 | static Signal::Ptr OnUpdate; 27 | 28 | static Signal<>::Ptr OnFixedUpdate; 29 | 30 | static void Update(float dt); 31 | 32 | static void FixedUpdate(); 33 | 34 | static void Shutdown(); 35 | 36 | static std::pair GetGLVersion(); 37 | }; 38 | } 39 | 40 | #endif // _FURY_ENGINE_H_ -------------------------------------------------------------------------------- /engine/Fury/Entity.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/Entity.h" 2 | #include "Fury/Log.h" 3 | 4 | namespace fury 5 | { 6 | Entity::Ptr Entity::Create(const std::string &name) 7 | { 8 | return std::make_shared(name); 9 | } 10 | 11 | Entity::Entity(const std::string &name) : m_TypeIndex(typeid(Entity)) 12 | { 13 | SetName(name); 14 | } 15 | 16 | std::type_index Entity::GetTypeIndex() const 17 | { 18 | return m_TypeIndex; 19 | } 20 | 21 | bool Entity::Load(const void* wrapper, bool object) 22 | { 23 | if (object && !IsObject(wrapper)) 24 | { 25 | FURYE << "Json node is not an object!"; 26 | return false; 27 | } 28 | 29 | if (!LoadMemberValue(wrapper, "name", m_Name)) 30 | { 31 | FURYE << "Name not found!"; 32 | return false; 33 | } 34 | SetName(m_Name); 35 | 36 | return true; 37 | } 38 | 39 | void Entity::Save(void* wrapper, bool object) 40 | { 41 | if (object) 42 | StartObject(wrapper); 43 | 44 | SaveKey(wrapper, "name"); 45 | SaveValue(wrapper, m_Name); 46 | 47 | if (object) 48 | EndObject(wrapper); 49 | } 50 | 51 | std::string Entity::GetName() const 52 | { 53 | return m_Name; 54 | } 55 | 56 | size_t Entity::GetHashCode() const 57 | { 58 | return m_HashCode; 59 | } 60 | 61 | size_t Entity::SetName(const std::string &name) 62 | { 63 | m_Name = name; 64 | m_HashCode = std::hash()(name); 65 | return m_HashCode; 66 | } 67 | } -------------------------------------------------------------------------------- /engine/Fury/Entity.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_ENTITY_H_ 2 | #define _FURY_ENTITY_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/TypeComparable.h" 8 | #include "Fury/Serializable.h" 9 | 10 | namespace fury 11 | { 12 | class FURY_API Entity : public TypeComparable, public Serializable 13 | { 14 | public: 15 | 16 | typedef std::shared_ptr Ptr; 17 | 18 | static Ptr Create(const std::string &name); 19 | 20 | Entity(const std::string &name); 21 | 22 | virtual ~Entity() {} 23 | 24 | virtual std::type_index GetTypeIndex() const; 25 | 26 | virtual bool Load(const void* wrapper, bool object = true); 27 | 28 | virtual void Save(void* wrapper, bool object = true); 29 | 30 | std::string GetName() const; 31 | 32 | size_t GetHashCode() const; 33 | 34 | size_t SetName(const std::string &name); 35 | 36 | protected: 37 | 38 | std::type_index m_TypeIndex; 39 | 40 | std::string m_Name; 41 | 42 | size_t m_HashCode; 43 | }; 44 | } 45 | 46 | #endif // _FURY_ENTITY_H_ -------------------------------------------------------------------------------- /engine/Fury/EntityManager.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_ENTITY_MANAGER_H_ 2 | #define _FURY_ENTITY_MANAGER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Macros.h" 10 | 11 | namespace fury 12 | { 13 | class FURY_API EntityManager final 14 | { 15 | public: 16 | 17 | typedef std::unordered_map>> TypeMap; 18 | 19 | typedef std::shared_ptr Ptr; 20 | 21 | static Ptr Create() 22 | { 23 | return std::make_shared(); 24 | } 25 | 26 | // class ObjectType must have function 'size_t GetHashCode()'. 27 | template 28 | bool Add(std::shared_ptr pointer) 29 | { 30 | std::type_index key0 = typeid(ObjectType); 31 | size_t key1 = pointer->GetHashCode(); 32 | 33 | auto it0 = m_EntityMap.find(key0); 34 | if (it0 == m_EntityMap.end()) 35 | { 36 | m_EntityMap[key0].emplace(key1, std::static_pointer_cast(pointer)); 37 | return true; 38 | } 39 | 40 | auto it1 = it0->second.find(key1); 41 | if (it1 == it0->second.end()) 42 | { 43 | m_EntityMap[key0].emplace(key1, std::static_pointer_cast(pointer)); 44 | return true; 45 | } 46 | 47 | return false; 48 | } 49 | 50 | template 51 | std::shared_ptr Remove(size_t hashcode) 52 | { 53 | std::type_index key0 = typeid(ObjectType); 54 | size_t key1 = hashcode; 55 | 56 | auto it0 = m_EntityMap.find(key0); 57 | if (it0 == m_EntityMap.end()) 58 | return nullptr; 59 | 60 | auto it1 = it0->second.find(key1); 61 | if (it1 == it0->second.end()) 62 | return nullptr; 63 | 64 | auto ptr = it1->second; 65 | it0->second.erase(it1); 66 | 67 | return std::static_pointer_cast(ptr); 68 | } 69 | 70 | template 71 | std::shared_ptr Remove(const std::string &name) 72 | { 73 | return Remove(std::hash()(name)); 74 | } 75 | 76 | template 77 | void RemoveAll() 78 | { 79 | auto it0 = m_EntityMap.find(typeid(ObjectType)); 80 | if (it0 != m_EntityMap.end()) 81 | it0->second.clear(); 82 | } 83 | 84 | void RemoveAll() 85 | { 86 | m_EntityMap.clear(); 87 | } 88 | 89 | template 90 | size_t Count() 91 | { 92 | auto it0 = m_EntityMap.find(typeid(ObjectType)); 93 | if (it0 != m_EntityMap.end()) 94 | return it0->second.size(); 95 | else 96 | return 0; 97 | } 98 | 99 | template 100 | std::shared_ptr Get(size_t hashcode) 101 | { 102 | std::type_index key0 = typeid(ObjectType); 103 | size_t key1 = hashcode; 104 | 105 | auto it0 = m_EntityMap.find(key0); 106 | if (it0 == m_EntityMap.end()) 107 | return nullptr; 108 | 109 | auto it1 = it0->second.find(key1); 110 | if (it1 == it0->second.end()) 111 | return nullptr; 112 | 113 | return std::static_pointer_cast(it1->second); 114 | } 115 | 116 | template 117 | std::shared_ptr Get(const std::string &name) 118 | { 119 | return Get(std::hash()(name)); 120 | } 121 | 122 | template 123 | std::unordered_map>::iterator Begin() 124 | { 125 | std::type_index key0 = typeid(ObjectType); 126 | 127 | auto it0 = m_EntityMap.find(key0); 128 | if (it0 != m_EntityMap.end()) 129 | return it0->second.begin(); 130 | 131 | return std::unordered_map>::iterator(); 132 | } 133 | 134 | template 135 | std::unordered_map>::iterator End() 136 | { 137 | std::type_index key0 = typeid(ObjectType); 138 | 139 | auto it0 = m_EntityMap.find(key0); 140 | if (it0 != m_EntityMap.end()) 141 | return it0->second.end(); 142 | 143 | return std::unordered_map>::iterator(); 144 | } 145 | 146 | // return false in your functor to break the loop. 147 | template 148 | void ForEach(const std::function&)> &func) 149 | { 150 | std::type_index key0 = typeid(ObjectType); 151 | 152 | auto it0 = m_EntityMap.find(key0); 153 | if (it0 == m_EntityMap.end()) 154 | return; 155 | 156 | for (auto it1 = it0->second.begin(); it1 != it0->second.end(); ++it1) 157 | { 158 | auto ptr = std::static_pointer_cast(it1->second); 159 | if (!func(ptr)) 160 | break; 161 | } 162 | } 163 | 164 | private: 165 | 166 | TypeMap m_EntityMap; 167 | }; 168 | } 169 | 170 | #endif // _FURY_ENTITY_MANAGER_H_ -------------------------------------------------------------------------------- /engine/Fury/FbxParser.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/engine/Fury/FbxParser.cpp -------------------------------------------------------------------------------- /engine/Fury/FbxParser.h: -------------------------------------------------------------------------------- 1 | #ifdef _FURY_FBXPARSER_IMP_ 2 | 3 | #ifndef _FURY_FBXPARSER_H_ 4 | #define _FURY_FBXPARSER_H_ 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "Fury/Singleton.h" 11 | #include "Fury/Entity.h" 12 | #include "Fury/Matrix4.h" 13 | 14 | namespace fury 15 | { 16 | class SceneNode; 17 | 18 | class Mesh; 19 | 20 | class Material; 21 | 22 | // assume int takes 16bits 23 | enum FbxImportFlags : unsigned int 24 | { 25 | UV = 0x0001, 26 | NORMAL = 0x0002, 27 | TANGENT = 0x0004, 28 | SPECULAR_MAP = 0x0008, 29 | NORMAL_MAP = 0x0010, 30 | OPTIMIZE_MESH = 0x0020, 31 | TRIANGULATE = 0x0040, 32 | IMP_ANIM = 0x0080, 33 | IMP_POS_ANIM = 0x0100, 34 | IMP_SCL_ANIM = 0x0200, 35 | BAKE_CURVE_ANIM = 0x0400, 36 | OPTIMIZE_ANIM = 0x0800, 37 | BAKE_LAYERS = 0x1000, 38 | AUTO_PAIR_CLIP = 0x2000 39 | }; 40 | 41 | struct FbxImportOptions 42 | { 43 | public: 44 | 45 | unsigned int Flags = FbxImportFlags::UV | FbxImportFlags::NORMAL | FbxImportFlags::IMP_ANIM | 46 | FbxImportFlags::IMP_POS_ANIM | FbxImportFlags::AUTO_PAIR_CLIP | FbxImportFlags::BAKE_CURVE_ANIM | 47 | FbxImportFlags::OPTIMIZE_MESH; 48 | 49 | float ScaleFactor = 1.0f; 50 | 51 | // 1 - 0 52 | float AnimCompressLevel = 0.5f; 53 | 54 | std::unordered_map> AnimLinkMap; 55 | }; 56 | 57 | class FURY_API FbxParser : public Singleton 58 | { 59 | protected: 60 | 61 | FbxScene* m_FbxScene = nullptr; 62 | 63 | FbxManager* m_FbxManager = nullptr; 64 | 65 | FbxImportOptions m_ImportOptions; 66 | 67 | FbxColor m_AmbientColor; 68 | 69 | std::string m_FbxFolder; 70 | 71 | std::unordered_map>> m_SkinnedMeshMap; 72 | 73 | public: 74 | 75 | typedef std::shared_ptr Ptr; 76 | 77 | typedef std::unordered_map> AnimLinkMap; 78 | 79 | void LoadScene(const std::string &filePath, const std::shared_ptr &rootNode, FbxImportOptions importOptions); 80 | 81 | protected: 82 | 83 | void LoadAnimations(const AnimLinkMap &animLinkMap); 84 | 85 | void LoadNode(const std::shared_ptr &ntNode, FbxNode *fbxNode); 86 | 87 | void LoadMesh(const std::shared_ptr &ntNode, FbxNode *fbxNode); 88 | 89 | void LoadMaterial(const std::shared_ptr &ntNode, FbxNode *fbxNode); 90 | 91 | void LoadLight(const std::shared_ptr &ntNode, FbxNode *fbxNode); 92 | 93 | std::shared_ptr CreatePhongMaterial(FbxSurfacePhong *fbxPhong); 94 | 95 | std::shared_ptr CreateLambertMaterial(FbxSurfaceLambert *fbxLambert); 96 | 97 | std::shared_ptr CreateMesh(const std::shared_ptr &ntNode, FbxNode *fbxNode); 98 | 99 | bool CreateSkeleton(const std::shared_ptr &ntNode, const std::shared_ptr &mesh, FbxMesh *fbxMesh); 100 | 101 | FbxAMatrix GetGeometryMatrix(FbxNode* fbxNode); 102 | 103 | Matrix4 FbxMatrixToFuryMatrix(const FbxAMatrix &fbxMatrix); 104 | 105 | void ApplyFbxAMatrixToNode(const std::shared_ptr &ntNode, const FbxAMatrix &fbxMatrix, bool scale = true); 106 | }; 107 | } 108 | 109 | #endif // _FURY_FBXPARSER_H_ 110 | 111 | #endif // _FURY_FBXPARSER_IMP_ -------------------------------------------------------------------------------- /engine/Fury/FileUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_FILEUTIL_H_ 2 | #define _FURY_FILEUTIL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Fury/EnumUtil.h" 10 | 11 | #undef LoadString 12 | #undef LoadImage 13 | 14 | namespace fury 15 | { 16 | class GLTFAccessor; 17 | 18 | class GLTFDom; 19 | 20 | class Mesh; 21 | 22 | class Pipeline; 23 | 24 | class Scene; 25 | 26 | class Serializable; 27 | 28 | enum GLTFImportFlags : unsigned int 29 | { 30 | OPTMZ_MESH = 0x0001, 31 | GEN_NORMAL = 0x0002, 32 | GEN_TANGENT = 0x0004, 33 | }; 34 | 35 | class FURY_API FileUtil final 36 | { 37 | private: 38 | 39 | static std::string m_AbsPath; 40 | 41 | static unsigned int* m_UIntBuffer; 42 | static int m_UIntBufferLength; 43 | 44 | static unsigned short* m_UShortBuffer; 45 | static int m_UShortBufferLength; 46 | 47 | static unsigned char* m_UCharBuffer; 48 | static int m_UCharBufferLength; 49 | 50 | static float* m_FloatBuffer; 51 | static int m_FloatBufferLength; 52 | 53 | static short* m_ShortBuffer; 54 | static int m_ShortBufferLength; 55 | 56 | static char* m_CharBuffer; 57 | static int m_CharBufferLength; 58 | 59 | public: 60 | 61 | static std::string GetAbsPath(); 62 | 63 | static std::string GetAbsPath(const std::string &source, bool toForwardSlash = false); 64 | 65 | static bool FileExist(const std::string &path); 66 | 67 | // image, text file io 68 | 69 | static bool LoadString(const std::string &path, std::string &output); 70 | 71 | static bool LoadImage(const std::string &path, std::vector &output, int &width, int &height, int &channels); 72 | 73 | // serializable obj io 74 | 75 | static bool LoadFile(const std::shared_ptr &source, const std::string &filePath); 76 | 77 | static bool SaveFile(const std::shared_ptr &source, const std::string &filePath, int maxDecimalPlaces = 5); 78 | 79 | static bool LoadCompressedFile(const std::shared_ptr &source, const std::string &filePath); 80 | 81 | static bool SaveCompressedFile(const std::shared_ptr &source, const std::string &filePath, int maxDecimalPlaces = 5); 82 | 83 | static bool LoadGLTFFile(const std::shared_ptr &scene, const std::string &jsonPath, const unsigned int options = 0); 84 | 85 | private: 86 | 87 | static bool PrivateLoadGLTFFile(const std::shared_ptr &gltfDom, std::vector> &buffers, 88 | const std::shared_ptr &scene, const std::string &workingDir, const unsigned int options); 89 | 90 | template 91 | static int AccessBuffer(const std::shared_ptr &gltfDom, std::vector> &buffers, 92 | const std::shared_ptr &accessor, std::vector &output); 93 | 94 | template 95 | static T* ResizeDataBuffer(T* buffer, int &oldLength, int newLength); 96 | 97 | static void DeleteDataBuffers(); 98 | }; 99 | } 100 | 101 | #endif // _FURY_FILEUTIL_H_ -------------------------------------------------------------------------------- /engine/Fury/Frustum.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_FRUSTUM_H_ 2 | #define _FURY_FRUSTUM_H_ 3 | 4 | #include 5 | 6 | #include "Fury/Collidable.h" 7 | #include "Fury/Plane.h" 8 | #include "Fury/Matrix4.h" 9 | 10 | namespace fury 11 | { 12 | class BoxBounds; 13 | 14 | class SphereBounds; 15 | 16 | class FURY_API Frustum : public Collidable 17 | { 18 | private: 19 | 20 | std::array m_BaseCorners; 21 | 22 | std::array m_CurrentCorners; 23 | 24 | std::array m_Planes; 25 | 26 | // left, right, bottom, top, near, far 27 | std::array m_ProjectionParams; 28 | 29 | Matrix4 m_Transform; 30 | 31 | public: 32 | 33 | Frustum() {} 34 | 35 | Frustum(const Frustum &other); 36 | 37 | void Setup(float fov, float ratio, float near, float far); 38 | 39 | void Setup(float left, float right, float bottom, float top, float near, float far); 40 | 41 | void Transform(const Matrix4 &matrix); 42 | 43 | virtual Side IsInside(const SphereBounds &bsphere) const; 44 | 45 | virtual Side IsInside(const BoxBounds &aabb) const; 46 | 47 | virtual Side IsInside(Vector4 point) const; 48 | 49 | virtual bool IsInsideFast(const SphereBounds &bsphere) const; 50 | 51 | virtual bool IsInsideFast(const BoxBounds &aabb) const; 52 | 53 | virtual bool IsInsideFast(Vector4 point) const; 54 | 55 | // ntl, ntr, nbl, nbr, ftl, ftr, fbl, fbr 56 | std::array GetCurrentCorners() const; 57 | 58 | std::array GetBaseCorners() const; 59 | 60 | Matrix4 GetTransformMatrix() const; 61 | 62 | BoxBounds GetBoxBounds() const; 63 | }; 64 | } 65 | 66 | #endif // _FURY_FRUSTUM_H_ -------------------------------------------------------------------------------- /engine/Fury/Fury.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_FURY_H_ 2 | #define _FURY_FURY_H_ 3 | 4 | #include "Fury/AnimationClip.h" 5 | #include "Fury/AnimationPlayer.h" 6 | #include "Fury/AnimationUtil.h" 7 | #include "Fury/ArrayBuffers.h" 8 | #include "Fury/BoxBounds.h" 9 | #include "Fury/Buffer.h" 10 | #include "Fury/BufferManager.h" 11 | #include "Fury/Camera.h" 12 | #include "Fury/Component.h" 13 | #include "Fury/Color.h" 14 | #include "Fury/Collidable.h" 15 | #include "Fury/Engine.h" 16 | #include "Fury/Entity.h" 17 | #include "Fury/EntityManager.h" 18 | #include "Fury/FileUtil.h" 19 | #include "Fury/FbxParser.h" 20 | #include "Fury/Frustum.h" 21 | #include "Fury/Gui.h" 22 | #include "Fury/InputUtil.h" 23 | #include "Fury/Joint.h" 24 | #include "Fury/Light.h" 25 | #include "Fury/Log.h" 26 | #include "Fury/MathUtil.h" 27 | #include "Fury/Material.h" 28 | #include "Fury/Matrix4.h" 29 | #include "Fury/Mesh.h" 30 | #include "Fury/MeshRender.h" 31 | #include "Fury/MeshUtil.h" 32 | #include "Fury/OcTree.h" 33 | #include "Fury/OcTreeNode.h" 34 | #include "Fury/Plane.h" 35 | #include "Fury/Quaternion.h" 36 | #include "Fury/Pass.h" 37 | #include "Fury/Pipeline.h" 38 | #include "Fury/PrelightPipeline.h" 39 | #include "Fury/RenderQuery.h" 40 | #include "Fury/RenderUtil.h" 41 | #include "Fury/Scene.h" 42 | #include "Fury/SceneNode.h" 43 | #include "Fury/Serializable.h" 44 | #include "Fury/Signal.h" 45 | #include "Fury/Shader.h" 46 | #include "Fury/Singleton.h" 47 | #include "Fury/SphereBounds.h" 48 | #include "Fury/Texture.h" 49 | #include "Fury/ThreadUtil.h" 50 | #include "Fury/Transform.h" 51 | #include "Fury/TypeComparable.h" 52 | #include "Fury/Uniform.h" 53 | #include "Fury/Vector4.h" 54 | 55 | #endif // _FURY_FURY_H_ -------------------------------------------------------------------------------- /engine/Fury/Gui.h: -------------------------------------------------------------------------------- 1 | #ifdef _FURY_GUI_IMP_ 2 | 3 | #ifndef _FURY_GUI_H_ 4 | #define _FURY_GUI_H_ 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include "Fury/Macros.h" 13 | 14 | struct ImDrawData; 15 | 16 | namespace fury 17 | { 18 | namespace Gui 19 | { 20 | bool FURY_API Initialize(sf::Window *window, float scale = 1.0f); 21 | 22 | void FURY_API Shutdown(); 23 | 24 | void FURY_API HandleEvent(sf::Event &event); 25 | 26 | void FURY_API NewFrame(float frameTime); 27 | 28 | void FURY_API RenderDrawLists(ImDrawData* draw_data); 29 | 30 | void FURY_API ShowDefault(float dt); 31 | 32 | void FURY_API Render(); 33 | } 34 | } 35 | 36 | #endif // _FURY_GUI_H_ 37 | 38 | #endif // _FURY_GUI_IMP_ -------------------------------------------------------------------------------- /engine/Fury/InputUtil.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/InputUtil.h" 2 | 3 | namespace fury 4 | { 5 | InputUtil::InputUtil(int winWidth, int winHeight) 6 | : m_WindowSize(winWidth, winHeight), m_MousePosition(0, 0) 7 | { 8 | for (int i = 0; i < sf::Mouse::Button::ButtonCount; i++) 9 | m_MouseDown[i] = false; 10 | 11 | for (int i = 0; i < sf::Keyboard::Key::KeyCount; i++) 12 | m_KeyDown[i] = false; 13 | } 14 | 15 | void InputUtil::GetWindowSize(int &width, int &height) 16 | { 17 | width = m_WindowSize.first; 18 | height = m_WindowSize.second; 19 | } 20 | 21 | std::pair InputUtil::GetMousePosition() 22 | { 23 | return m_MousePosition; 24 | } 25 | 26 | bool InputUtil::GetWindowFocused() 27 | { 28 | return m_WindowFocused; 29 | } 30 | 31 | float InputUtil::GetMouseWheel() 32 | { 33 | return m_MouseWheel; 34 | } 35 | 36 | bool InputUtil::GetMouseDown() 37 | { 38 | for (int i = 0; i < sf::Mouse::Button::ButtonCount; i++) 39 | { 40 | if (m_MouseDown[i]) 41 | return true; 42 | } 43 | return false; 44 | } 45 | 46 | bool InputUtil::GetMouseDown(sf::Mouse::Button btn) 47 | { 48 | return m_MouseDown[btn]; 49 | } 50 | 51 | bool InputUtil::GetKeyDown(sf::Keyboard::Key key) 52 | { 53 | return m_KeyDown[key]; 54 | } 55 | } -------------------------------------------------------------------------------- /engine/Fury/InputUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_INPUT_UTIL_H_ 2 | #define _FURY_INPUT_UTIL_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Signal.h" 8 | #include "Fury/Singleton.h" 9 | #include "Fury/EnumUtil.h" 10 | 11 | namespace fury 12 | { 13 | class FURY_API InputUtil final : public Singleton 14 | { 15 | friend class Engine; 16 | 17 | public: 18 | 19 | typedef std::shared_ptr Ptr; 20 | 21 | private: 22 | 23 | std::pair m_WindowSize; 24 | 25 | std::pair m_MousePosition; 26 | 27 | bool m_WindowFocused = false; 28 | 29 | bool m_MouseInWindow = true; 30 | 31 | float m_MouseWheel = 0.0f; 32 | 33 | bool m_MouseDown[sf::Mouse::Button::ButtonCount]; 34 | 35 | bool m_KeyDown[sf::Keyboard::Key::KeyCount]; 36 | 37 | public: 38 | 39 | Signal::Ptr OnKeyDown = Signal::Create(); 40 | 41 | Signal::Ptr OnKeyUp = Signal::Create(); 42 | 43 | Signal<>::Ptr OnWindowClosed = Signal<>::Create(); 44 | 45 | Signal::Ptr OnWindowResized = Signal::Create(); 46 | 47 | // true for focused, false for losing. 48 | Signal::Ptr OnWindowFocus = Signal::Create(); 49 | 50 | // unicode 51 | Signal::Ptr OnTextEntered = Signal::Create(); 52 | 53 | // true for entering window, false for lefting. 54 | Signal::Ptr OnMouseEnter = Signal::Create(); 55 | 56 | // offset (ppositive up/left), x & y relative to window's top & left owner. 57 | Signal::Ptr OnMouseWheel = Signal::Create(); 58 | 59 | // x & y relative to window's top & left owner. 60 | Signal::Ptr OnMouseMove = Signal::Create(); 61 | 62 | // x & y relative to window's top & left owner. 63 | Signal::Ptr OnMouseDown = Signal::Create(); 64 | 65 | Signal::Ptr OnMouseUp = Signal::Create(); 66 | 67 | InputUtil(int winWidth, int winHeight); 68 | 69 | void GetWindowSize(int &width, int &height); 70 | 71 | std::pair GetMousePosition(); 72 | 73 | bool GetWindowFocused(); 74 | 75 | float GetMouseWheel(); 76 | 77 | bool GetMouseDown(); 78 | 79 | bool GetMouseDown(sf::Mouse::Button btn); 80 | 81 | bool GetKeyDown(sf::Keyboard::Key key); 82 | }; 83 | } 84 | 85 | #endif // _FURY_INPUT_UTIL_H_ -------------------------------------------------------------------------------- /engine/Fury/Joint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "Fury/Log.h" 4 | #include "Fury/Mesh.h" 5 | #include "Fury/Joint.h" 6 | 7 | namespace fury 8 | { 9 | std::shared_ptr Joint::Create(const std::string &name, const std::shared_ptr &mesh) 10 | { 11 | return std::make_shared(name, mesh); 12 | } 13 | 14 | std::shared_ptr Joint::FindFromRoot(const std::string &name, const std::shared_ptr &root) 15 | { 16 | size_t nameHash = std::hash()(name); 17 | if (root->m_HashCode == nameHash) 18 | return root; 19 | 20 | Joint::Ptr joint0 = root, joint1 = nullptr; 21 | std::stack jointStack; 22 | jointStack.push(joint0); 23 | 24 | while (!jointStack.empty()) 25 | { 26 | joint0 = jointStack.top(); 27 | jointStack.pop(); 28 | joint1 = joint0->m_FirstChild; 29 | while (joint1 != nullptr) 30 | { 31 | if (joint1->m_HashCode == nameHash) 32 | return joint1; 33 | if (joint1->m_FirstChild != nullptr) 34 | jointStack.push(joint1); 35 | joint1 = joint1->m_Sibling; 36 | } 37 | } 38 | 39 | return nullptr; 40 | } 41 | 42 | Joint::Joint(const std::string &name, const std::shared_ptr &mesh) : 43 | Entity(name), m_Mesh(mesh) 44 | { 45 | m_TypeIndex = typeid(Joint); 46 | } 47 | 48 | Joint::~Joint() 49 | { 50 | m_Mesh.reset(); 51 | m_Parent.reset(); 52 | m_FirstChild = nullptr; 53 | m_Sibling = nullptr; 54 | //FURYD << "Joint " << m_Name << " destoried!"; 55 | } 56 | 57 | void Joint::Update(const Matrix4 &matrix) 58 | { 59 | m_CombinedMatrix = matrix * m_LocalMatrix; 60 | m_FinalMatrix = m_CombinedMatrix * m_OffsetMatrix; 61 | if (m_Sibling != nullptr) 62 | m_Sibling->Update(matrix); 63 | if (m_FirstChild != nullptr) 64 | m_FirstChild->Update(m_CombinedMatrix); 65 | } 66 | 67 | void Joint::Update(float dt) 68 | { 69 | m_LocalMatrix.Translate(m_Position.first + (m_Position.second - m_Position.first) * dt); 70 | m_LocalMatrix.AppendRotation(m_Rotation.first.Slerp(m_Rotation.second, dt)); 71 | m_LocalMatrix.AppendScale(m_Scaling.first + (m_Scaling.second - m_Scaling.first) * dt); 72 | } 73 | 74 | void Joint::SetRotation(Quaternion rot, bool old) 75 | { 76 | (old ? m_Rotation.first : m_Rotation.second) = rot; 77 | } 78 | 79 | void Joint::SetPosition(Vector4 pos, bool old) 80 | { 81 | (old ? m_Position.first : m_Position.second) = pos; 82 | } 83 | 84 | void Joint::SetScaling(Vector4 scl, bool old) 85 | { 86 | (old ? m_Scaling.first : m_Scaling.second) = scl; 87 | } 88 | 89 | Quaternion Joint::GetRotation(bool old) 90 | { 91 | return old ? m_Rotation.first : m_Rotation.second; 92 | } 93 | 94 | Vector4 Joint::GetPosition(bool old) 95 | { 96 | return old ? m_Position.first : m_Position.second; 97 | } 98 | 99 | Vector4 Joint::GetScaling(bool old) 100 | { 101 | return old ? m_Scaling.first : m_Scaling.second; 102 | } 103 | 104 | void Joint::SetLocalMatrix(const Matrix4 &matrix) 105 | { 106 | m_LocalMatrix = matrix; 107 | } 108 | 109 | Matrix4 Joint::GetLocalMatrix() const 110 | { 111 | return m_LocalMatrix; 112 | } 113 | 114 | void Joint::SetCombinedMatrix(const Matrix4 &matrix) 115 | { 116 | m_CombinedMatrix = matrix; 117 | } 118 | 119 | Matrix4 Joint::GetCombinedMatrix() const 120 | { 121 | return m_CombinedMatrix; 122 | } 123 | 124 | void Joint::SetOffsetMatrix(const Matrix4 &matrix) 125 | { 126 | m_OffsetMatrix = matrix; 127 | } 128 | 129 | Matrix4 Joint::GetOffsetMatrix() const 130 | { 131 | return m_OffsetMatrix; 132 | } 133 | 134 | Matrix4 Joint::GetFinalMatrix() 135 | { 136 | return m_FinalMatrix; 137 | } 138 | 139 | Joint::Ptr Joint::GetFirstChild() const 140 | { 141 | return m_FirstChild; 142 | } 143 | 144 | void Joint::SetFirstChild(const Joint::Ptr &joint) 145 | { 146 | m_FirstChild = joint; 147 | } 148 | 149 | Joint::Ptr Joint::GetSibling() const 150 | { 151 | return m_Sibling; 152 | } 153 | 154 | void Joint::SetSibling(const Joint::Ptr &joint) 155 | { 156 | m_Sibling = joint; 157 | } 158 | 159 | Joint::Ptr Joint::GetParent() const 160 | { 161 | return m_Parent.lock(); 162 | } 163 | 164 | void Joint::SetParent(const Joint::Ptr &joint) 165 | { 166 | m_Parent = joint; 167 | } 168 | 169 | std::shared_ptr Joint::GetMesh() const 170 | { 171 | return m_Mesh.lock(); 172 | } 173 | } -------------------------------------------------------------------------------- /engine/Fury/Joint.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_JOINT_H_ 2 | #define _FURY_JOINT_H_ 3 | 4 | #include "Fury/Entity.h" 5 | #include "Fury/Matrix4.h" 6 | #include "Fury/Quaternion.h" 7 | 8 | namespace fury 9 | { 10 | class Mesh; 11 | 12 | class FURY_API Joint final : public Entity 13 | { 14 | public: 15 | 16 | friend class Shader; 17 | 18 | typedef std::shared_ptr Ptr; 19 | 20 | static Ptr Create(const std::string &name, const std::shared_ptr &mesh); 21 | 22 | static Ptr FindFromRoot(const std::string &name, const Ptr &root); 23 | 24 | protected: 25 | 26 | std::weak_ptr m_Mesh; 27 | 28 | Joint::Ptr m_FirstChild; 29 | 30 | Joint::Ptr m_Sibling; 31 | 32 | std::weak_ptr m_Parent; 33 | 34 | Matrix4 m_LocalMatrix; 35 | 36 | Matrix4 m_CombinedMatrix; 37 | 38 | Matrix4 m_OffsetMatrix; 39 | 40 | Matrix4 m_FinalMatrix; 41 | 42 | std::pair m_Position; 43 | 44 | std::pair m_Rotation; 45 | 46 | std::pair m_Scaling; 47 | 48 | public: 49 | 50 | Joint(const std::string &name, const std::shared_ptr &mesh); 51 | 52 | ~Joint(); 53 | 54 | void Update(const Matrix4 &matrix); 55 | 56 | // update local matrix by interpolated TRS value pairs. 57 | void Update(float dt); 58 | 59 | void SetRotation(Quaternion rot, bool old = false); 60 | 61 | void SetPosition(Vector4 pos, bool old = false); 62 | 63 | void SetScaling(Vector4 scl, bool old = false); 64 | 65 | Quaternion GetRotation(bool old = false); 66 | 67 | Vector4 GetPosition(bool old = false); 68 | 69 | Vector4 GetScaling(bool old = false); 70 | 71 | void SetLocalMatrix(const Matrix4 &matrix); 72 | 73 | Matrix4 GetLocalMatrix() const; 74 | 75 | void SetCombinedMatrix(const Matrix4 &matrix); 76 | 77 | Matrix4 GetCombinedMatrix() const; 78 | 79 | void SetOffsetMatrix(const Matrix4 &matrix); 80 | 81 | Matrix4 GetOffsetMatrix() const; 82 | 83 | Matrix4 GetFinalMatrix(); 84 | 85 | Joint::Ptr GetFirstChild() const; 86 | 87 | void SetFirstChild(const Joint::Ptr &joint); 88 | 89 | Joint::Ptr GetSibling() const; 90 | 91 | void SetSibling(const Joint::Ptr &joint); 92 | 93 | Joint::Ptr GetParent() const; 94 | 95 | void SetParent(const Joint::Ptr &joint); 96 | 97 | std::shared_ptr GetMesh() const; 98 | }; 99 | } 100 | 101 | #endif // _FURY_JOINT_H_ -------------------------------------------------------------------------------- /engine/Fury/Light.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_LIGHT_H_ 2 | #define _FURY_LIGHT_H_ 3 | 4 | #include "Fury/Component.h" 5 | #include "Fury/BoxBounds.h" 6 | #include "Fury/Color.h" 7 | #include "Fury/EnumUtil.h" 8 | 9 | namespace fury 10 | { 11 | class Mesh; 12 | 13 | // light's default direction is (0,-1,0,0) 14 | class FURY_API Light : public Component 15 | { 16 | public: 17 | 18 | typedef std::shared_ptr Ptr; 19 | 20 | static Ptr Create(); 21 | 22 | private: 23 | 24 | LightType m_Type = LightType::POINT; 25 | 26 | Color m_Color = Color::White; 27 | 28 | float m_Intensity = 1.0f; 29 | 30 | float m_InnerAngle = 45.0f; 31 | 32 | float m_OutterAngle = 45.0f; 33 | 34 | float m_Falloff = 0.0f; 35 | 36 | float m_Radius = 0.0f; 37 | 38 | bool m_CastShadows = false; 39 | 40 | BoxBounds m_AABB; 41 | 42 | std::shared_ptr m_Mesh; 43 | 44 | public: 45 | 46 | Light(); 47 | 48 | virtual bool Load(const void* wrapper, bool object = true) override; 49 | 50 | virtual void Save(void* wrapper, bool object = true) override; 51 | 52 | Component::Ptr Clone() const override; 53 | 54 | LightType GetType() const; 55 | 56 | void SetType(LightType type); 57 | 58 | void SetColor(Color color); 59 | 60 | Color GetColor() const; 61 | 62 | void SetIntensity(float value); 63 | 64 | float GetIntensity() const; 65 | 66 | // in radian 67 | void SetInnerAngle(float value); 68 | 69 | float GetInnerAngle() const; 70 | 71 | // in radian 72 | void SetOutterAngle(float value); 73 | 74 | float GetOutterAngle() const; 75 | 76 | void SetFalloff(float value); 77 | 78 | float GetFalloff() const; 79 | 80 | void SetRadius(float value); 81 | 82 | float GetRadius() const; 83 | 84 | void SetCastShadows(bool cast); 85 | 86 | bool GetCastShadows() const; 87 | 88 | BoxBounds GetAABB() const; 89 | 90 | void CalculateAABB(); 91 | 92 | // Convex Volume that defines light's shape. 93 | std::shared_ptr GetMesh(); 94 | 95 | // Create a mesh shaped by light's params. 96 | std::shared_ptr EvaluateVolume(); 97 | 98 | protected: 99 | 100 | virtual void OnAttaching(const std::shared_ptr &node) override; 101 | 102 | virtual void OnDetaching(const std::shared_ptr &node) override; 103 | }; 104 | } 105 | 106 | #endif // _FURY_LIGHT_H_ -------------------------------------------------------------------------------- /engine/Fury/Macros.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_MACROS_H_ 2 | #define _FURY_MACROS_H_ 3 | 4 | #include 5 | 6 | #if defined(_WIN32) 7 | 8 | #ifdef FURY_API_EXPORT 9 | #define FURY_API __declspec(dllexport) 10 | #else 11 | #define FURY_API __declspec(dllimport) 12 | #endif 13 | 14 | // For Visual C++ compilers, we also need to turn off this annoying C4251 warning 15 | #ifdef _MSC_VER 16 | #pragma warning(disable: 4251) 17 | #endif 18 | 19 | #else 20 | 21 | #define FURY_API 22 | 23 | #endif 24 | 25 | #ifndef NDEBUG 26 | #define ASSERT_MSG(condition, message) \ 27 | do { \ 28 | if (! (condition)) { \ 29 | std::cerr << "Assertion failed: (" #condition "), function " << __FUNCTION__ \ 30 | << ", file " << __FILE__ << ", line " << __LINE__ << ": " << message << std::endl; \ 31 | std::abort(); \ 32 | } \ 33 | } while (false) 34 | #else 35 | #define ASSERT_MSG(condition, message) \ 36 | do {} while (false) 37 | #endif 38 | 39 | #define FURY_MIPMAP_LEVEL 5 40 | 41 | #endif // _FURY_MACROS_H_ -------------------------------------------------------------------------------- /engine/Fury/Material.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_MATERIALS_H_ 2 | #define _FURY_MATERIALS_H_ 3 | 4 | #include 5 | 6 | #include "Fury/Entity.h" 7 | #include "Fury/EnumUtil.h" 8 | #include "Fury/Buffer.h" 9 | 10 | namespace fury 11 | { 12 | class UniformBase; 13 | 14 | class Texture; 15 | 16 | class Shader; 17 | 18 | class FURY_API Material : public Entity, public Buffer 19 | { 20 | public: 21 | 22 | friend class Shader; 23 | 24 | typedef std::shared_ptr Ptr; 25 | 26 | typedef std::unordered_map> TextureMap; 27 | 28 | typedef std::unordered_map> UniformMap; 29 | 30 | static const std::string DIFFUSE_TEXTURE; 31 | 32 | static const std::string SPECULAR_TEXTURE; 33 | 34 | static const std::string NORMAL_TEXTURE; 35 | 36 | static const std::string SHININESS; 37 | 38 | static const std::string TRANSPARENCY; 39 | 40 | static const std::string AMBIENT_FACTOR; 41 | 42 | static const std::string DIFFUSE_FACTOR; 43 | 44 | static const std::string SPECULAR_FACTOR; 45 | 46 | static const std::string EMISSIVE_FACTOR; 47 | 48 | static const std::string AMBIENT_COLOR; 49 | 50 | static const std::string DIFFUSE_COLOR; 51 | 52 | static const std::string SPECULAR_COLOR; 53 | 54 | static const std::string EMISSIVE_COLOR; 55 | 56 | static const std::string MATERIAL_ID; 57 | 58 | static Ptr Create(const std::string &name); 59 | 60 | private: 61 | 62 | static unsigned int m_GlobalID; 63 | 64 | protected: 65 | 66 | unsigned int GetMaterialID(); 67 | 68 | TextureMap m_Textures; 69 | 70 | UniformMap m_Uniforms; 71 | 72 | std::vector> m_Shaders; 73 | 74 | unsigned int m_TextureFlags; 75 | 76 | bool m_Opaque; 77 | 78 | unsigned int m_ID; 79 | 80 | public: 81 | 82 | Material(const std::string &name); 83 | 84 | virtual ~Material(); 85 | 86 | virtual bool Load(const void* wrapper, bool object = true) override; 87 | 88 | virtual void Save(void* wrapper, bool object = true) override; 89 | 90 | virtual void UpdateBuffer() override; 91 | 92 | virtual void DeleteBuffer() override; 93 | 94 | unsigned int GetTextureFlags() const; 95 | 96 | std::shared_ptr GetTexture(const std::string &name) const; 97 | 98 | void SetTexture(const std::string &name, const std::shared_ptr &ptr); 99 | 100 | unsigned int GetTextureCount() const; 101 | 102 | void SetUniform(const std::string &name, const std::shared_ptr &ptr); 103 | 104 | std::shared_ptr GetUniform(const std::string &name); 105 | 106 | unsigned int GetUniformCount() const; 107 | 108 | void SetShaderForPass(unsigned int index, const std::shared_ptr &shader); 109 | 110 | std::shared_ptr GetShaderForPass(unsigned int index); 111 | 112 | bool GetOpaque() const; 113 | 114 | void SetOpaque(bool value); 115 | 116 | // get this material's unique identifier for rendering. 117 | unsigned int GetID() const; 118 | }; 119 | } 120 | 121 | #endif // _FURY_MATERIALS_H_ -------------------------------------------------------------------------------- /engine/Fury/MathUtil.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "Fury/MathUtil.h" 4 | #include "Fury/SceneNode.h" 5 | 6 | namespace fury 7 | { 8 | const float MathUtil::PI = 3.1415926536f; 9 | 10 | const float MathUtil::HalfPI = 1.5707963268f; 11 | 12 | // PI / 180 13 | const float MathUtil::DegToRad = 0.0174532925f; 14 | 15 | // 180 / PI 16 | const float MathUtil::RadToDeg = 57.295779513f; 17 | 18 | float MathUtil::DegreeToRadian(float deg) 19 | { 20 | return deg * DegToRad; 21 | } 22 | 23 | float MathUtil::RadianToDegree(float rad) 24 | { 25 | return rad * RadToDeg; 26 | } 27 | 28 | Quaternion MathUtil::AxisRadToQuat(Vector4 axis, float rad) 29 | { 30 | float t2 = rad * .5f; 31 | float st2 = std::sin(t2); 32 | return Quaternion(axis.x * st2, axis.y * st2, 33 | axis.z * st2, std::cos(t2)); 34 | } 35 | 36 | Quaternion MathUtil::AxisRadToQuat(Vector4 axisRad) 37 | { 38 | return AxisRadToQuat(axisRad, axisRad.w); 39 | } 40 | 41 | Vector4 MathUtil::AxisRadToEulerRad(Vector4 axis, float rad) 42 | { 43 | Vector4 eulerRadian; 44 | 45 | float s = sin(rad); 46 | float c = cos(rad); 47 | float t = 1 - c; 48 | 49 | if ((axis.x * axis.y * t + axis.z * s) > 0.998f) 50 | { 51 | // north pole singularity detected 52 | eulerRadian.x = 2 * atan2(axis.x * sin(axis.w / 2), cos(axis.w / 2)); 53 | eulerRadian.y = 0; 54 | eulerRadian.z = PI / 2; 55 | } 56 | else if ((axis.x * axis.y * t + axis.z * s) < -0.998f) 57 | { 58 | // south pole singularity detected 59 | eulerRadian.x = -2 * atan2(axis.x * sin(axis.w / 2), cos(axis.w / 2)); 60 | eulerRadian.y = 0; 61 | eulerRadian.y = -PI / 2; 62 | } 63 | else 64 | { 65 | eulerRadian.x = atan2( 66 | axis.y * s - axis.x * axis.z * t, 67 | 1 - (axis.y * axis.y + axis.z * axis.z) * t 68 | ); 69 | eulerRadian.y = atan2( 70 | axis.x * s - axis.y * axis.z * t, 71 | 1 - (axis.x * axis.x + axis.z * axis.z) * t 72 | ); 73 | eulerRadian.z = asin(axis.x * axis.y * t + axis.z * s); 74 | } 75 | 76 | return eulerRadian; 77 | } 78 | 79 | Vector4 MathUtil::AxisRadToEulerRad(Vector4 axisRad) 80 | { 81 | return AxisRadToEulerRad(axisRad, axisRad.w); 82 | } 83 | 84 | Quaternion MathUtil::EulerRadToQuat(Vector4 eulerRad) 85 | { 86 | return EulerRadToQuat(eulerRad.x, eulerRad.y, eulerRad.z); 87 | } 88 | 89 | Quaternion MathUtil::EulerRadToQuat(float yaw, float pitch, float roll) 90 | { 91 | float cx = std::cos(yaw / 2); 92 | float sx = std::sin(yaw / 2); 93 | float cy = std::cos(pitch / 2); 94 | float sy = std::sin(pitch / 2); 95 | float cz = std::cos(roll / 2); 96 | float sz = std::sin(roll / 2); 97 | 98 | return Quaternion( 99 | sx * sz * cy + cx * cz * sy, 100 | sx * cz * cy + cx * sz * sy, 101 | cx * sz * cy - sx * cz * sy, 102 | cx * cz * cy - sx * sz * sy 103 | ); 104 | } 105 | 106 | Vector4 MathUtil::QuatToAxisRad(Quaternion quat) 107 | { 108 | Vector4 axisRadian; 109 | axisRadian.w = std::acos(quat.w) * 2.0f; 110 | 111 | float a = 1.0f - quat.w * quat.w; 112 | if (a <= 0.0f) 113 | { 114 | axisRadian.x = 1.0f; 115 | axisRadian.y = axisRadian.z = 0.0f; 116 | } 117 | else 118 | { 119 | float b = 1.0f / std::sqrt(a); 120 | axisRadian.x = quat.x * b; 121 | axisRadian.y = quat.y * b; 122 | axisRadian.z = quat.z * b; 123 | } 124 | 125 | return axisRadian; 126 | } 127 | 128 | Vector4 MathUtil::QuatToEulerRad(Quaternion quat) 129 | { 130 | return AxisRadToEulerRad(QuatToAxisRad(quat)); 131 | } 132 | 133 | bool MathUtil::PointInCone(Vector4 coneCenter, Vector4 coneDir, float height, float theta, Vector4 point) 134 | { 135 | float cosTheta = std::cos(theta); 136 | float cosTheta2 = cosTheta * cosTheta; 137 | 138 | Vector4 dir = point - coneCenter; 139 | float dot = coneDir * dir; 140 | 141 | if (dot >= 0 && dot * dot >= cosTheta2 * (dir * dir) && 142 | (dir.Project(coneDir).SquareLength() <= height * height)) 143 | return true; 144 | 145 | return false; 146 | } 147 | } -------------------------------------------------------------------------------- /engine/Fury/MathUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_MATHUTIL_H_ 2 | #define _FURY_MATHUTIL_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Quaternion.h" 8 | #include "Fury/Vector4.h" 9 | #include "Fury/Matrix4.h" 10 | 11 | namespace fury 12 | { 13 | class SceneNode; 14 | 15 | // Euler in YXZ order. 16 | class FURY_API MathUtil 17 | { 18 | public: 19 | 20 | static const float PI; 21 | 22 | static const float HalfPI; 23 | 24 | static const float DegToRad; 25 | 26 | static const float RadToDeg; 27 | 28 | static float DegreeToRadian(float deg); 29 | 30 | static float RadianToDegree(float rad); 31 | 32 | static Quaternion AxisRadToQuat(Vector4 axis, float rad); 33 | 34 | static Quaternion AxisRadToQuat(Vector4 axisRad); 35 | 36 | static Vector4 AxisRadToEulerRad(Vector4 axis, float rad); 37 | 38 | static Vector4 AxisRadToEulerRad(Vector4 axisRad); 39 | 40 | static Quaternion EulerRadToQuat(Vector4 eulerRad); 41 | 42 | static Quaternion EulerRadToQuat(float yaw, float pitch, float roll); 43 | 44 | static Vector4 QuatToAxisRad(Quaternion quat); 45 | 46 | static Vector4 QuatToEulerRad(Quaternion quat); 47 | 48 | static bool PointInCone(Vector4 coneCenter, Vector4 coneDir, float height, float theta, Vector4 point); 49 | 50 | }; 51 | } 52 | 53 | #endif // _FURY_MATHUTIL_H_ -------------------------------------------------------------------------------- /engine/Fury/Matrix4.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_MATRIX4_H_ 2 | #define _FURY_MATRIX4_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Macros.h" 8 | 9 | namespace fury 10 | { 11 | class BoxBounds; 12 | 13 | class Quaternion; 14 | 15 | class Vector4; 16 | 17 | class Plane; 18 | 19 | /** 20 | * Matrix stores position info in Raw[12, 13, 14] like opengl. 21 | * 0 4 8 12 22 | * 1 5 9 13 23 | * 2 6 10 14 24 | * 3 7 11 15 25 | */ 26 | class FURY_API Matrix4 27 | { 28 | public: 29 | 30 | static std::string PROJECTION_MATRIX; 31 | 32 | static std::string INVERT_VIEW_MATRIX; 33 | 34 | static std::string WORLD_MATRIX; 35 | 36 | float Raw[16]; 37 | 38 | Matrix4(); 39 | 40 | Matrix4(const float raw[]); 41 | 42 | Matrix4(const float raw[], const int offset); 43 | 44 | Matrix4(std::initializer_list raw); 45 | 46 | Matrix4(const Matrix4 &other); 47 | 48 | void Identity(); 49 | 50 | void Translate(Vector4 position); 51 | 52 | void AppendTranslation(Vector4 position); 53 | 54 | void PrependTranslation(Vector4 position); 55 | 56 | void Rotate(Quaternion rotation); 57 | 58 | void AppendRotation(Quaternion rotation); 59 | 60 | void PrependRotation(Quaternion rotation); 61 | 62 | void Scale(Vector4 scale); 63 | 64 | void AppendScale(Vector4 scale); 65 | 66 | void PrependScale(Vector4 scale); 67 | 68 | void PerspectiveFov(float fov, float ratio, float near, float far); 69 | 70 | void PerspectiveOffCenter(float left, float right, float bottom, float top, float near, float far); 71 | 72 | void OrthoOffCenter(float left, float right, float bottom, float top, float near, float far); 73 | 74 | void LookAt(Vector4 eye, Vector4 at, Vector4 up); 75 | 76 | Matrix4 Transpose() const; 77 | 78 | Vector4 Multiply(Vector4 data) const; 79 | 80 | Quaternion Multiply(Quaternion data) const; 81 | 82 | BoxBounds Multiply(const BoxBounds &data) const; 83 | 84 | Plane Multiply(const Plane &data) const; 85 | 86 | // No projection term 87 | Matrix4 Inverse() const; 88 | 89 | Matrix4 Clone() const; 90 | 91 | bool operator == (const Matrix4 &other) const; 92 | 93 | bool operator != (const Matrix4 &other) const; 94 | 95 | Matrix4 &operator = (const Matrix4 &other); 96 | 97 | Matrix4 operator * (const Matrix4 &other) const; 98 | }; 99 | 100 | } 101 | 102 | #endif // _FURY_MATRIX4_H_ -------------------------------------------------------------------------------- /engine/Fury/Mesh.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_MESH_H_ 2 | #define _FURY_MESH_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Entity.h" 8 | #include "Fury/ArrayBuffers.h" 9 | #include "Fury/BoxBounds.h" 10 | #include "Fury/Buffer.h" 11 | 12 | namespace fury 13 | { 14 | class FURY_API SubMesh final : public Buffer, public TypeComparable 15 | { 16 | public: 17 | 18 | friend class Shader; 19 | 20 | typedef std::shared_ptr Ptr; 21 | 22 | static Ptr Create(); 23 | 24 | protected: 25 | 26 | std::type_index m_TypeIndex; 27 | 28 | unsigned int m_VAO; 29 | 30 | public: 31 | 32 | ArrayBufferui Indices; 33 | 34 | SubMesh(); 35 | 36 | ~SubMesh(); 37 | 38 | virtual void UpdateBuffer() override; 39 | 40 | virtual void DeleteBuffer() override; 41 | 42 | // if ur mesh is static, and won't change after import. 43 | // call this to free the memory allocated for vertex data. 44 | void DeleteRawData(); 45 | 46 | virtual std::type_index GetTypeIndex() const override; 47 | }; 48 | 49 | class Joint; 50 | 51 | // TODO: Add read only property 52 | class FURY_API Mesh : public Entity, public Buffer 53 | { 54 | public: 55 | 56 | friend class Shader; 57 | 58 | friend class FbxParser; 59 | 60 | typedef std::shared_ptr Ptr; 61 | 62 | static Ptr Create(const std::string &name); 63 | 64 | protected: 65 | 66 | unsigned int m_VAO; 67 | 68 | BoxBounds m_AABB; 69 | 70 | std::vector m_SubMeshes; 71 | 72 | std::unordered_map> m_JointMap; 73 | 74 | std::vector> m_Joints; 75 | 76 | std::shared_ptr m_RootJoint; 77 | 78 | bool m_CastShadows = false; 79 | 80 | public: 81 | 82 | ArrayBufferf Positions; 83 | 84 | ArrayBufferf Normals; 85 | 86 | ArrayBufferf Tangents; 87 | 88 | ArrayBufferf UVs; 89 | 90 | ArrayBufferf Weights; 91 | 92 | ArrayBufferui IDs; 93 | 94 | ArrayBufferui Indices; 95 | 96 | Mesh(const std::string &name); 97 | 98 | virtual ~Mesh(); 99 | 100 | virtual bool Load(const void* wrapper, bool object = true) override; 101 | 102 | virtual void Save(void* wrapper, bool object = true) override; 103 | 104 | void AddSubMesh(const SubMesh::Ptr &subMesh); 105 | 106 | SubMesh::Ptr GetSubMeshAt(unsigned int index) const; 107 | 108 | unsigned int GetSubMeshCount() const; 109 | 110 | bool IsSkinnedMesh() const; 111 | 112 | std::shared_ptr GetJoint(const std::string &name) const; 113 | 114 | std::shared_ptr GetJointAt(unsigned int index) const; 115 | 116 | // this returns the count of joints that influences mesh's vertices. 117 | unsigned int GetJointCount() const; 118 | 119 | std::shared_ptr GetRootJoint() const; 120 | 121 | virtual void UpdateBuffer() override; 122 | 123 | virtual void DeleteBuffer() override; 124 | 125 | void CalculateAABB(const Vector4& min, const Vector4& max); 126 | 127 | void CalculateAABB(); 128 | 129 | BoxBounds GetAABB() const; 130 | 131 | bool GetCastShadows() const; 132 | 133 | void SetCastShadows(bool state); 134 | }; 135 | } 136 | 137 | #endif // _FURY_MESH_H_ -------------------------------------------------------------------------------- /engine/Fury/MeshRender.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/engine/Fury/MeshRender.cpp -------------------------------------------------------------------------------- /engine/Fury/MeshRender.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_MESHRENDER_H_ 2 | #define _FURY_MESHRENDER_H_ 3 | 4 | #include "Fury/Component.h" 5 | 6 | namespace fury 7 | { 8 | class Material; 9 | 10 | class Mesh; 11 | 12 | class FURY_API MeshRender : public Component 13 | { 14 | public: 15 | 16 | typedef std::shared_ptr Ptr; 17 | 18 | static Ptr Create(const std::shared_ptr &material, const std::shared_ptr &mesh); 19 | 20 | protected: 21 | 22 | std::vector> m_Materials; 23 | 24 | std::weak_ptr m_Mesh; 25 | 26 | public: 27 | 28 | MeshRender(const std::shared_ptr &material, const std::shared_ptr &mesh); 29 | 30 | virtual bool Load(const void* wrapper, bool object = true) override; 31 | 32 | virtual void Save(void* wrapper, bool object = true) override; 33 | 34 | Component::Ptr Clone() const override; 35 | 36 | void UpdateBuffer(); 37 | 38 | // if index exceeds material.size(). 39 | // it will append ur material to the end of the vector. 40 | void SetMaterial(const std::shared_ptr &material, unsigned int index = 0); 41 | 42 | std::shared_ptr GetMaterial(unsigned int index = 0) const; 43 | 44 | unsigned int GetMaterialCount() const; 45 | 46 | void SetMesh(const std::shared_ptr &mesh); 47 | 48 | std::shared_ptr GetMesh() const; 49 | 50 | bool GetRenderable() const; 51 | 52 | protected: 53 | 54 | virtual void OnAttaching(const std::shared_ptr &node) override; 55 | 56 | virtual void OnDetaching(const std::shared_ptr &node) override; 57 | }; 58 | } 59 | 60 | #endif // _FURY_MESHRENDER_H_ -------------------------------------------------------------------------------- /engine/Fury/MeshUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_MESHUTIL_H_ 2 | #define _FURY_MESHUTIL_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Macros.h" 8 | #include "Fury/Matrix4.h" 9 | 10 | namespace fury 11 | { 12 | class Mesh; 13 | 14 | class FURY_API MeshUtil final 15 | { 16 | friend class Engine; 17 | 18 | private: 19 | 20 | static std::shared_ptr m_UnitCube; 21 | 22 | static std::shared_ptr m_UnitQuad; 23 | 24 | static std::shared_ptr m_UnitSphere; 25 | 26 | static std::shared_ptr m_UnitIcoSphere; 27 | 28 | static std::shared_ptr m_UnitCylinder; 29 | 30 | static std::shared_ptr m_UnitCone; 31 | 32 | public: 33 | 34 | static std::shared_ptr GetUnitCube(); 35 | 36 | static std::shared_ptr GetUnitQuad(); 37 | 38 | static std::shared_ptr GetUnitSphere(); 39 | 40 | static std::shared_ptr GetUnitIcoSphere(); 41 | 42 | static std::shared_ptr GetUnitCylinder(); 43 | 44 | static std::shared_ptr GetUnitCone(); 45 | 46 | static std::shared_ptr CreateQuad(const std::string &name, Vector4 min, Vector4 max); 47 | 48 | static std::shared_ptr CreateCube(const std::string &name, Vector4 min, Vector4 max); 49 | 50 | static std::shared_ptr CreateIcoSphere(const std::string &name, float radius, int level); 51 | 52 | static std::shared_ptr CreateSphere(const std::string &name, float radius, int segH, int segV); 53 | 54 | static std::shared_ptr CreateCylinder(const std::string &name, float topR, float bottomR, float height, 55 | int segH, int segV); 56 | 57 | static void TransformMesh(const std::shared_ptr &mesh, const Matrix4 &matrix, bool updateBuffer = false); 58 | 59 | // restruct mesh's data by finding & removing possible reapet vertices. 60 | static void OptimizeMesh(const std::shared_ptr &mesh); 61 | 62 | // you should calculate normal first, then optimize ur mesh. 63 | static void CalculateNormal(const std::shared_ptr &mesh); 64 | 65 | // TODO: test 66 | // you should calculate normal first, then calculate tangent. 67 | static void CalculateTangent(const std::shared_ptr &mesh); 68 | }; 69 | } 70 | 71 | #endif // _FURY_MESHUTIL_H_ -------------------------------------------------------------------------------- /engine/Fury/OcTree.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_OCTREE_H_ 2 | #define _FURY_OCTREE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "Fury/Color.h" 9 | #include "SceneManager.h" 10 | #include "Fury/Vector4.h" 11 | 12 | namespace fury 13 | { 14 | class OcTreeNode; 15 | 16 | // OcTree holds a shared_ptr to attached scenenodes. 17 | // When you need to destory a scenenode. 18 | // Call node.RemoveFromOcTree(true) + node.RemoveFromParent() + node.reset(). 19 | // You'll destory this node and all it's childs. 20 | class FURY_API OcTree : public SceneManager, public std::enable_shared_from_this 21 | { 22 | public: 23 | 24 | typedef std::shared_ptr Ptr; 25 | 26 | static Ptr Create(Vector4 min, Vector4 max, unsigned int maxDepth = 6); 27 | 28 | protected: 29 | 30 | std::type_index m_TypeIndex; 31 | 32 | std::shared_ptr m_Root; 33 | 34 | unsigned int m_MaxDepth; 35 | 36 | public: 37 | 38 | OcTree(Vector4 min, Vector4 max, unsigned int maxDepth); 39 | 40 | ~OcTree(); 41 | 42 | virtual std::type_index GetTypeIndex() const; 43 | 44 | virtual void AddSceneNode(const std::shared_ptr &sceneNode); 45 | 46 | virtual void AddSceneNodeRecursively(const std::shared_ptr &sceneNode); 47 | 48 | virtual void RemoveSceneNode(const std::shared_ptr &sceneNode); 49 | 50 | virtual void UpdateSceneNode(const std::shared_ptr &sceneNode); 51 | 52 | virtual void GetRenderQuery(const Collidable &collider, const std::shared_ptr &renderQuery, bool clear = true) const; 53 | 54 | virtual void GetVisibleSceneNodes(const Collidable &collider, SceneNodes &sceneNodes, bool clear = true) const; 55 | 56 | virtual void GetVisibleRenderables(const Collidable &collider, SceneNodes &renderables, bool clear = true) const; 57 | 58 | virtual void GetVisibleShadowCasters(const Collidable &collider, SceneNodes &renderables, bool clear = true) const; 59 | 60 | virtual void GetVisibleLights(const Collidable &collider, SceneNodes &lights, bool clear = true) const; 61 | 62 | virtual void GetVisibleRenderableAndLights(const Collidable &collider, SceneNodes &renderables, SceneNodes &lights, bool clear = true) const; 63 | 64 | virtual void WalkScene(const Collidable &collider, const FilterFunc &filterFunc) const; 65 | 66 | virtual void Reset(Vector4 min, Vector4 max, unsigned int maxDepth); 67 | 68 | virtual void Clear(); 69 | 70 | protected: 71 | 72 | void AddSceneNode(const std::shared_ptr &sceneNode, const std::shared_ptr &treeNode, unsigned int depth); 73 | 74 | }; 75 | } 76 | 77 | #endif // _FURY_OCTREE_H_ -------------------------------------------------------------------------------- /engine/Fury/OcTreeNode.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_OCTREENODE_H_ 2 | #define _FURY_OCTREENODE_H_ 3 | 4 | #include "Fury/SceneNode.h" 5 | 6 | namespace fury 7 | { 8 | class OcTree; 9 | 10 | /** 11 | 12 | Children layout: 13 | ____________ 14 | /__2__/__6_ / 15 | /__3__/__7__/ 16 | ____________ 17 | /__0__/__4_ / 18 | /__1__/__5__/ 19 | 20 | */ 21 | class FURY_API OcTreeNode : public TypeComparable, public std::enable_shared_from_this 22 | { 23 | friend class OcTree; 24 | 25 | public: 26 | 27 | typedef std::shared_ptr Ptr; 28 | 29 | static Ptr Create(OcTree &manager, const OcTreeNode::Ptr &parent, 30 | Vector4 min, Vector4 max); 31 | 32 | protected: 33 | 34 | std::type_index m_TypeIndex; 35 | 36 | BoxBounds m_AABB; 37 | 38 | OcTree& m_Manager; 39 | 40 | OcTreeNode::Ptr m_Childs[8]; 41 | 42 | std::vector> m_SceneNodes; 43 | 44 | OcTreeNode::Ptr m_Parent; 45 | 46 | bool m_IsLeaf; 47 | 48 | unsigned int m_TotalSceneNodeCount; 49 | 50 | public: 51 | 52 | OcTreeNode(OcTree &manager, const OcTreeNode::Ptr &parent, 53 | Vector4 min, Vector4 max); 54 | 55 | virtual ~OcTreeNode(); 56 | 57 | virtual std::type_index GetTypeIndex() const; 58 | 59 | BoxBounds GetAABB() const; 60 | 61 | OcTree &GetManager() const; 62 | 63 | bool IsTwiceSize(BoxBounds other) const; 64 | 65 | bool IsLeaf() const; 66 | 67 | OcTreeNode::Ptr GetFitNode(BoxBounds other); 68 | 69 | std::shared_ptr GetChildAt(unsigned int index) const; 70 | 71 | unsigned int GetSceneNodeCount() const; 72 | 73 | std::shared_ptr GetSceneNodeAt(unsigned int index) const; 74 | 75 | unsigned int GetTotalSceneNodeCount() const; 76 | 77 | void Clear(); 78 | 79 | void AddSceneNode(const std::shared_ptr &node); 80 | 81 | void RemoveSceneNode(const std::shared_ptr &node); 82 | 83 | protected: 84 | 85 | void IncreaseSceneNodeCount(); 86 | 87 | void DecreaseSceneNodeCount(); 88 | 89 | }; 90 | } 91 | 92 | #endif // _FURY_OCTREENODE_H_ -------------------------------------------------------------------------------- /engine/Fury/Pass.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_PASS_H_ 2 | #define _FURY_PASS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Color.h" 8 | #include "Fury/Entity.h" 9 | #include "Fury/EnumUtil.h" 10 | #include "Fury/Vector4.h" 11 | 12 | #undef OPAQUE 13 | #undef TRANSPARENT 14 | #undef IGNORE 15 | 16 | namespace fury 17 | { 18 | class SceneNode; 19 | 20 | class Shader; 21 | 22 | class Texture; 23 | 24 | class FURY_API Pass : public Entity 25 | { 26 | friend class FileUtil; 27 | 28 | public: 29 | 30 | typedef std::shared_ptr Ptr; 31 | 32 | static Ptr Create(const std::string &name); 33 | 34 | protected: 35 | 36 | std::vector> m_OutputTextures; 37 | 38 | std::vector> m_InputTextures; 39 | 40 | ClearMode m_ClearMode = ClearMode::COLOR_DEPTH_STENCIL; 41 | 42 | Color m_ClearColor = Color(0, 0, 0, 0); 43 | 44 | CompareMode m_CompareMode = CompareMode::LESS; 45 | 46 | BlendMode m_BlendMode = BlendMode::REPLACE; 47 | 48 | CullMode m_CullMode = CullMode::BACK; 49 | 50 | DrawMode m_DrawMode = DrawMode::OPAQUE; 51 | 52 | std::vector> m_Shaders; 53 | 54 | unsigned int m_RenderIndex = 0; 55 | 56 | unsigned int m_FrameBuffer = 0; 57 | 58 | unsigned int m_ColorAttachmentCount = 0; 59 | 60 | int m_ViewPortWidth = 0; 61 | 62 | int m_ViewPortHeight = 0; 63 | 64 | bool m_RenderTargetDirty = false; 65 | 66 | bool m_Binded = false; 67 | 68 | std::vector>> m_LayerTextures; 69 | 70 | std::vector>> m_CubeTextures; 71 | 72 | public: 73 | 74 | Pass(const std::string &name); 75 | 76 | virtual ~Pass(); 77 | 78 | virtual bool Load(const void* wrapper, bool object = true) override; 79 | 80 | virtual void Save(void* wrapper, bool object = true) override; 81 | 82 | void SetRenderIndex(unsigned int index); 83 | 84 | unsigned int GetRenderIndex() const; 85 | 86 | void SetClearMode(ClearMode mode); 87 | 88 | ClearMode GetClearMode() const; 89 | 90 | void SetClearColor(Color color); 91 | 92 | Color GetClearColor() const; 93 | 94 | void SetCompareMode(CompareMode mode); 95 | 96 | CompareMode GetCompareMode() const; 97 | 98 | void SetBlendMode(BlendMode mode); 99 | 100 | BlendMode GetBlendMode() const; 101 | 102 | void SetCullMode(CullMode mode); 103 | 104 | CullMode GetCullMode() const; 105 | 106 | void SetDrawMode(DrawMode mode); 107 | 108 | DrawMode GetDrawMode() const; 109 | 110 | // After binding, call this to specify the layer of the texture array to render to. 111 | void SetArrayTextureLayer(const std::string &name, int index); 112 | 113 | // After binding, call this to specify the layer of all texture array to render to. 114 | void SetArrayTextureLayer(int index); 115 | 116 | void SetCubeTextureIndex(const std::string &name, int index); 117 | 118 | void SetCubeTextureIndex(int index); 119 | 120 | int GetViewPortWidth() const; 121 | 122 | int GetViewPortHeight() const; 123 | 124 | void AddShader(const std::shared_ptr &shader); 125 | 126 | std::shared_ptr GetShader(ShaderType type, unsigned int textures = 0) const; 127 | 128 | std::shared_ptr GetFirstShader() const; 129 | 130 | unsigned int GetShaderCount() const; 131 | 132 | void AddTexture(const std::shared_ptr &texture, bool input); 133 | 134 | std::shared_ptr GetTextureAt(unsigned int index, bool input) const; 135 | 136 | std::shared_ptr RemoveTextureAt(unsigned int index, bool input); 137 | 138 | unsigned int GetTextureIndex(const std::string &name, bool input) const; 139 | 140 | std::shared_ptr GetTexture(const std::string &name, bool input) const; 141 | 142 | unsigned int GetTextureCount(bool input) const; 143 | 144 | unsigned int GetFBO() const; 145 | 146 | void RemoveAllTextures(); 147 | 148 | void CreateFrameBuffer(); 149 | 150 | void BindRenderTargets(); 151 | 152 | void UnBindRenderTargets(); 153 | 154 | void DeleteFrameBuffer(); 155 | 156 | void Clear(ClearMode mode, Color color = Color(0.0f, 0.0f, 0.0f, 0.0f)); 157 | 158 | void Bind(bool clear = true); 159 | 160 | void UnBind(); 161 | }; 162 | } 163 | 164 | #endif // _FURY_PASS_H_ -------------------------------------------------------------------------------- /engine/Fury/Pipeline.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_PIPELINE_H_ 2 | #define _FURY_PIPELINE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Fury/Entity.h" 10 | 11 | namespace fury 12 | { 13 | class BoxBounds; 14 | 15 | class Collidable; 16 | 17 | class Frustum; 18 | 19 | class Material; 20 | 21 | class Mesh; 22 | 23 | class Pass; 24 | 25 | class SceneNode; 26 | 27 | class SceneManager; 28 | 29 | class EntityManager; 30 | 31 | class Texture; 32 | 33 | class Shader; 34 | 35 | class SphereBounds; 36 | 37 | class RenderQuery; 38 | 39 | enum class PipelineSwitch : unsigned int 40 | { 41 | CASCADED_SHADOW_MAP = 0, 42 | MESH_BOUNDS, 43 | LIGHT_BOUNDS, 44 | CUSTOM_BOUNDS, 45 | LENGTH 46 | }; 47 | 48 | class FURY_API Pipeline : public Entity 49 | { 50 | friend class FileUtil; 51 | 52 | public: 53 | 54 | typedef std::shared_ptr Ptr; 55 | 56 | static Ptr Active; 57 | 58 | protected: 59 | 60 | std::shared_ptr m_EntityManager; 61 | 62 | std::vector m_SortedPasses; 63 | 64 | std::bitset<(size_t)PipelineSwitch::LENGTH> m_Switches; 65 | 66 | // rendering 67 | 68 | std::shared_ptr m_CurrentCamera; 69 | 70 | std::shared_ptr m_CurrentShader; 71 | 72 | std::shared_ptr m_CurrentMateral; 73 | 74 | std::shared_ptr m_CurrentMesh; 75 | 76 | std::shared_ptr m_SharedPass; 77 | 78 | Matrix4 m_OffsetMatrix; 79 | 80 | // end rendering 81 | 82 | // debug 83 | 84 | std::vector m_DebugBoxBounds; 85 | 86 | std::vector m_DebugFrustum; 87 | 88 | // end debug 89 | 90 | public: 91 | 92 | Pipeline(const std::string &name); 93 | 94 | virtual ~Pipeline(); 95 | 96 | virtual bool Load(const void* wrapper, bool object = true) override; 97 | 98 | virtual void Save(void* wrapper, bool object = true) override; 99 | 100 | virtual void Execute(const std::shared_ptr &sceneManager) = 0; 101 | 102 | // basiclly saves all pipeline && pass's textures, shaders 103 | std::shared_ptr GetEntityManager() const; 104 | 105 | void SetSwitch(PipelineSwitch key, bool value); 106 | 107 | bool IsSwitchOn(PipelineSwitch key); 108 | 109 | bool IsSwitchOn(std::initializer_list list, bool any = true); 110 | 111 | void ClearDebugCollidables(); 112 | 113 | void AddDebugCollidable(const BoxBounds &bounds); 114 | 115 | void AddDebugCollidable(const Frustum &bounds); 116 | 117 | std::shared_ptr GetPassByName(const std::string &name); 118 | 119 | std::shared_ptr GetTextureByName(const std::string &name); 120 | 121 | std::shared_ptr GetShaderByName(const std::string &name); 122 | 123 | std::shared_ptr GetCurrentCamera() const; 124 | 125 | void SetCurrentCamera(const std::shared_ptr &ptr); 126 | 127 | // begin shaodw mapping 128 | 129 | void FilterNodes(const Collidable &collider, std::vector> &possibles, std::vector> &collisions); 130 | 131 | Matrix4 GetCropMatrix(Matrix4 lightMatrix, Frustum frustum, std::vector> &casters); 132 | 133 | std::pair, std::vector> DrawCascadedShadowMap(const std::shared_ptr &sceneManager, const std::shared_ptr &pass, const std::shared_ptr &node); 134 | 135 | std::pair, Matrix4> DrawDirLightShadowMap(const std::shared_ptr &sceneManager, const std::shared_ptr &pass, const std::shared_ptr &node); 136 | 137 | std::pair, Matrix4> DrawPointLightShadowMap(const std::shared_ptr &sceneManager, const std::shared_ptr &pass, const std::shared_ptr &node); 138 | 139 | std::pair, Matrix4> DrawSpotLightShadowMap(const std::shared_ptr &sceneManager, const std::shared_ptr &pass, const std::shared_ptr &node); 140 | 141 | // end shaodw mapping 142 | 143 | protected: 144 | 145 | void DrawDebug(const std::shared_ptr &query); 146 | 147 | void SortPassByIndex(); 148 | }; 149 | } 150 | 151 | #endif // _FURY_PIPELINE_H_ -------------------------------------------------------------------------------- /engine/Fury/Plane.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "Fury/BoxBounds.h" 4 | #include "Fury/Plane.h" 5 | #include "Fury/SphereBounds.h" 6 | 7 | namespace fury 8 | { 9 | Plane::Plane() : m_Distance(0), m_Normal() {} 10 | 11 | Plane::Plane(float a, float b, float c, float d) : 12 | m_Normal(a, b, c, 0.0f), m_Distance(d) {} 13 | 14 | Plane::Plane(const Plane &other) 15 | : m_Normal(other.GetNormal()), m_Distance(other.GetDistance()) {} 16 | 17 | Plane::Plane(Vector4 p1, Vector4 p2, Vector4 p3) 18 | { 19 | Set3Points(p1, p2, p3); 20 | } 21 | 22 | Plane::Plane(Vector4 normal, Vector4 position) 23 | { 24 | SetNormalAndPosition(normal, position); 25 | } 26 | 27 | void Plane::Set3Points(Vector4 p1, Vector4 p2, Vector4 p3) 28 | { 29 | m_Normal = (p2 - p1).CrossProduct((p3 - p2)); 30 | m_Normal.Normalize(); 31 | m_Normal.w = 0.0f; 32 | m_Distance = -(p1 * m_Normal); 33 | } 34 | 35 | void Plane::SetNormalAndPosition(Vector4 normal, Vector4 position) 36 | { 37 | m_Normal = normal.Normalized(); 38 | m_Normal.w = 0.0f; 39 | m_Distance = -(normal * position); 40 | } 41 | 42 | Side Plane::IsInside(Vector4 point) const 43 | { 44 | float d = GetDistance(point); 45 | if (d > 0.0f) return Side::IN; 46 | if (d < 0.0f) return Side::OUT; 47 | return Side::STRADDLE; 48 | } 49 | 50 | Side Plane::IsInside(const BoxBounds &aabb) const 51 | { 52 | if (GetDistance(aabb.GetVertexP(m_Normal)) < 0.0f) 53 | return Side::OUT; 54 | if (GetDistance(aabb.GetVertexN(m_Normal)) < 0.0f) 55 | return Side::STRADDLE; 56 | return Side::IN; 57 | } 58 | 59 | Side Plane::IsInside(const SphereBounds &bsphere) const 60 | { 61 | float d = GetDistance(bsphere.GetCenter()); 62 | if (fabs(d) <= bsphere.GetRadius()) 63 | return Side::STRADDLE; 64 | 65 | return d > 0.0f ? Side::IN : Side::OUT; 66 | } 67 | 68 | bool Plane::IsInsideFast(Vector4 point) const 69 | { 70 | return GetDistance(point) >= 0.0f; 71 | } 72 | 73 | bool Plane::IsInsideFast(const BoxBounds &aabb) const 74 | { 75 | return GetDistance(aabb.GetVertexP(m_Normal)) >= 0.0f; 76 | } 77 | 78 | bool Plane::IsInsideFast(const SphereBounds &bsphere) const 79 | { 80 | return GetDistance(bsphere.GetCenter()) >= bsphere.GetRadius(); 81 | } 82 | 83 | float Plane::GetDistance(Vector4 point) const 84 | { 85 | return m_Normal.x * point.x + m_Normal.y * point.y + m_Normal.z * point.z + m_Distance; 86 | } 87 | 88 | Vector4 Plane::GetNormal() const 89 | { 90 | return m_Normal; 91 | } 92 | 93 | float Plane::GetDistance() const 94 | { 95 | return m_Distance; 96 | } 97 | 98 | Plane &Plane::operator = (Plane other) 99 | { 100 | m_Normal = other.GetNormal(); 101 | m_Distance = other.GetDistance(); 102 | return *this; 103 | } 104 | 105 | bool Plane::operator == (Plane other) const 106 | { 107 | return m_Normal == other.GetNormal() && m_Distance == other.GetDistance(); 108 | } 109 | 110 | bool Plane::operator != (Plane other) const 111 | { 112 | return m_Normal != other.GetNormal() || m_Distance != other.GetDistance(); 113 | } 114 | } -------------------------------------------------------------------------------- /engine/Fury/Plane.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_PLANE_H_ 2 | #define _FURY_PLANE_H_ 3 | 4 | #include "Fury/EnumUtil.h" 5 | #include "Fury/Vector4.h" 6 | 7 | namespace fury 8 | { 9 | class BoxBounds; 10 | 11 | class SphereBounds; 12 | 13 | class FURY_API Plane 14 | { 15 | protected: 16 | 17 | Vector4 m_Normal; 18 | 19 | float m_Distance; 20 | 21 | public: 22 | 23 | Plane(); 24 | 25 | Plane(float a, float b, float c, float d); 26 | 27 | Plane(const Plane &other); 28 | 29 | Plane(Vector4 p1, Vector4 p2, Vector4 p3); 30 | 31 | Plane(Vector4 normal, Vector4 position); 32 | 33 | // CCW 34 | void Set3Points(Vector4 p1, Vector4 p2, Vector4 p3); 35 | 36 | void SetNormalAndPosition(Vector4 normal, Vector4 position); 37 | 38 | Side IsInside(Vector4 point) const; 39 | 40 | Side IsInside(const BoxBounds &aabb) const; 41 | 42 | Side IsInside(const SphereBounds &bsphere) const; 43 | 44 | bool IsInsideFast(Vector4 point) const; 45 | 46 | bool IsInsideFast(const BoxBounds &aabb) const; 47 | 48 | bool IsInsideFast(const SphereBounds &bsphere) const; 49 | 50 | float GetDistance(Vector4 point) const; 51 | 52 | Vector4 GetNormal() const; 53 | 54 | float GetDistance() const; 55 | 56 | Plane &operator = (Plane other); 57 | 58 | bool operator == (Plane other) const; 59 | 60 | bool operator != (Plane other) const; 61 | 62 | }; 63 | } 64 | 65 | #endif // _FURY_PLANE_H_ -------------------------------------------------------------------------------- /engine/Fury/PrelightPipeline.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_PRELIGHT_PIPELINE_H_ 2 | #define _FURY_PRELIGHT_PIPELINE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "Fury/Pipeline.h" 11 | #include "Fury/Matrix4.h" 12 | 13 | namespace fury 14 | { 15 | class Texture; 16 | 17 | class Shader; 18 | 19 | class Pass; 20 | 21 | struct RenderUnit; 22 | 23 | class FURY_API PrelightPipeline : public Pipeline 24 | { 25 | public: 26 | 27 | typedef std::shared_ptr Ptr; 28 | 29 | static Ptr Create(const std::string &name); 30 | 31 | PrelightPipeline(const std::string &name); 32 | 33 | virtual bool Load(const void* wrapper, bool object = true) override; 34 | 35 | virtual void Save(void* wrapper, bool object = true) override; 36 | 37 | virtual void Execute(const std::shared_ptr &sceneManager) override; 38 | 39 | protected: 40 | 41 | void DrawUnit(const std::shared_ptr &pass, const RenderUnit &unit); 42 | 43 | void DrawPointLight(const std::shared_ptr &sceneManager, const std::shared_ptr &pass, const std::shared_ptr &node); 44 | 45 | void DrawDirLight(const std::shared_ptr &sceneManager, const std::shared_ptr &pass, const std::shared_ptr &node); 46 | 47 | void DrawSpotLight(const std::shared_ptr &sceneManager, const std::shared_ptr &pass, const std::shared_ptr &node); 48 | 49 | void DrawQuad(const std::shared_ptr &pass); 50 | }; 51 | } 52 | 53 | #endif // _FURY_PRELIGHT_PIPELINE_H_ -------------------------------------------------------------------------------- /engine/Fury/Quaternion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "Fury/Quaternion.h" 4 | #include "Fury/Vector4.h" 5 | 6 | namespace fury 7 | { 8 | void Quaternion::Identity() 9 | { 10 | x = y = z = 0.0f; 11 | w = 1.0f; 12 | } 13 | 14 | float Quaternion::DotProduct(Quaternion other) const 15 | { 16 | return w * other.w + x * other.x + y * other.y + z * other.z; 17 | } 18 | 19 | Quaternion Quaternion::Slerp(Quaternion other, float dt) const 20 | { 21 | float cosom = DotProduct(other); 22 | Quaternion end = other; 23 | 24 | if (cosom < 0.0f) 25 | { 26 | cosom = -cosom; 27 | end.x = -end.x; 28 | end.y = -end.y; 29 | end.z = -end.z; 30 | end.w = -end.w; 31 | } 32 | 33 | float k0, k1; 34 | if(cosom > 0.9999f) 35 | { 36 | k0 = 1.0f - dt; 37 | k1 = dt; 38 | } 39 | else 40 | { 41 | float omega = std::acos(cosom); 42 | float sinom = std::sin(omega); 43 | k0 = std::sin((1.0f - dt) * omega) / sinom; 44 | k1 = std::sin(dt * omega) / sinom; 45 | } 46 | 47 | end.x = k0 * x + k1 * end.x; 48 | end.y = k0 * y + k1 * end.y; 49 | end.z = k0 * z + k1 * end.z; 50 | end.w = k0 * w + k1 * end.w; 51 | 52 | return end; 53 | } 54 | 55 | Quaternion Quaternion::Conjugate() const 56 | { 57 | Quaternion other; 58 | 59 | other.x = -x; 60 | other.y = -y; 61 | other.z = -z; 62 | other.w = w; 63 | 64 | return other; 65 | } 66 | 67 | Quaternion Quaternion::Pow(float exp) const 68 | { 69 | if(std::abs(w) > .9999f) return *this; 70 | 71 | float alpha = std::acos(w); 72 | float alpha2 = alpha * exp; 73 | float mul = std::sin(alpha2) / std::sin(alpha); 74 | 75 | Quaternion other; 76 | 77 | other.w = std::cos(alpha2); 78 | other.x = x * mul; 79 | other.y = y * mul; 80 | other.z = z * mul; 81 | 82 | return other; 83 | } 84 | 85 | void Quaternion::Normalize() 86 | { 87 | float mag = std::sqrt(x * x + y * y + z * z + w * w); 88 | if(mag > 0.0f) 89 | { 90 | mag = 1 / mag; 91 | w *= mag; 92 | x *= mag; 93 | y *= mag; 94 | z *= mag; 95 | } 96 | else 97 | { 98 | Identity(); 99 | } 100 | } 101 | 102 | Quaternion Quaternion::Clone() const 103 | { 104 | return Quaternion(*this); 105 | } 106 | 107 | bool Quaternion::operator == (Quaternion other) const 108 | { 109 | return x == other.x && y == other.y && z == other.z && w == other.w; 110 | } 111 | 112 | bool Quaternion::operator != (Quaternion other) const 113 | { 114 | return x != other.x || y != other.y || z != other.z || w != other.w; 115 | } 116 | 117 | Quaternion &Quaternion::operator = (Quaternion other) 118 | { 119 | x = other.x; y = other.y; z = other.z; w = other.w; 120 | return *this; 121 | } 122 | 123 | Quaternion Quaternion::operator * (Quaternion other) const 124 | { 125 | return Quaternion( 126 | w * other.x + x * other.w + y * other.z - z * other.y, 127 | w * other.y - x * other.z + y * other.w + z * other.x, 128 | w * other.z + x * other.y - y * other.x + z * other.w, 129 | w * other.w - x * other.x - y * other.y - z * other.z 130 | ); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /engine/Fury/Quaternion.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_QUATERNION_H_ 2 | #define _FURY_QUATERNION_H_ 3 | 4 | #include "Macros.h" 5 | 6 | namespace fury 7 | { 8 | class Vector4; 9 | 10 | class FURY_API Quaternion 11 | { 12 | public: 13 | 14 | float x, y, z, w; 15 | 16 | Quaternion() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) {} 17 | 18 | Quaternion(const Quaternion &other) : x(other.x), y(other.y), z(other.z), w(other.w) {} 19 | 20 | Quaternion(float nx, float ny, float nz, float nw) : x(nx), y(ny), z(nz), w(nw) {} 21 | 22 | void Identity(); 23 | 24 | float DotProduct(Quaternion other) const; 25 | 26 | Quaternion Slerp(Quaternion other, float dt) const; 27 | 28 | Quaternion Conjugate() const; 29 | 30 | Quaternion Pow(float exp) const; 31 | 32 | void Normalize(); 33 | 34 | Quaternion Clone() const; 35 | 36 | bool operator == (Quaternion other) const; 37 | 38 | bool operator != (Quaternion other) const; 39 | 40 | Quaternion &operator = (Quaternion other); 41 | 42 | Quaternion operator * (Quaternion other) const; 43 | }; 44 | } 45 | 46 | #endif // _FURY_QUATERNION_H_ -------------------------------------------------------------------------------- /engine/Fury/RenderQuery.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "Fury/RenderQuery.h" 5 | #include "Fury/SceneNode.h" 6 | #include "Fury/MeshRender.h" 7 | #include "Fury/Material.h" 8 | #include "Fury/Mesh.h" 9 | 10 | #include "Fury/Log.h" 11 | #include "Fury/Light.h" 12 | 13 | namespace fury 14 | { 15 | RenderQuery::Ptr RenderQuery::Create() 16 | { 17 | return std::make_shared(); 18 | } 19 | 20 | void RenderQuery::AddRenderable(const std::shared_ptr &node) 21 | { 22 | auto render = node->GetComponent(); 23 | auto mesh = render->GetMesh(); 24 | auto subMeshCount = mesh->GetSubMeshCount(); 25 | if (subMeshCount > 0) 26 | { 27 | for (unsigned int i = 0; i < subMeshCount; i++) 28 | { 29 | auto subMesh = mesh->GetSubMeshAt(i); 30 | auto material = render->GetMaterial(i); 31 | if (material->GetOpaque()) 32 | opaqueUnits.push_back(RenderUnit(node, mesh, material, i)); 33 | else 34 | transparentUnits.push_back(RenderUnit(node, mesh, material, i)); 35 | } 36 | } 37 | else 38 | { 39 | auto material = render->GetMaterial(); 40 | if (material->GetOpaque()) 41 | opaqueUnits.push_back(RenderUnit(node, mesh, material, -1)); 42 | else 43 | transparentUnits.push_back(RenderUnit(node, mesh, material, -1)); 44 | } 45 | 46 | renderableNodes.push_back(node); 47 | } 48 | 49 | void RenderQuery::AddLight(const std::shared_ptr &node) 50 | { 51 | lightNodes.push_back(node); 52 | } 53 | 54 | void RenderQuery::Sort(Vector4 camPos) 55 | { 56 | std::sort(opaqueUnits.begin(), opaqueUnits.end(), [&camPos](const RenderUnit &a, const RenderUnit &b) -> bool 57 | { 58 | return a.node->GetWorldPosition().Distance(camPos) < b.node->GetWorldPosition().Distance(camPos); 59 | }); 60 | 61 | std::sort(transparentUnits.begin(), transparentUnits.end(), [&camPos](const RenderUnit &a, const RenderUnit &b) -> bool 62 | { 63 | return a.node->GetWorldPosition().Distance(camPos) > b.node->GetWorldPosition().Distance(camPos); 64 | }); 65 | 66 | /*std::sort(lightNodes.begin(), lightNodes.end(), [](const SceneNode::Ptr &a, const SceneNode::Ptr &b) -> bool 67 | { 68 | return b->GetComponent()->GetCastShadows(); 69 | });*/ 70 | } 71 | 72 | void RenderQuery::Clear() 73 | { 74 | opaqueUnits.clear(); 75 | transparentUnits.clear(); 76 | renderableNodes.clear(); 77 | lightNodes.clear(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /engine/Fury/RenderQuery.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_RENDERQUERY_H_ 2 | #define _FURY_RENDERQUERY_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Vector4.h" 8 | 9 | namespace fury 10 | { 11 | class SceneNode; 12 | 13 | class Material; 14 | 15 | class Mesh; 16 | 17 | struct FURY_API RenderUnit 18 | { 19 | std::shared_ptr node; 20 | 21 | std::shared_ptr mesh; 22 | 23 | std::shared_ptr material; 24 | 25 | int subMesh = 0; 26 | 27 | RenderUnit(const std::shared_ptr &node, const std::shared_ptr &mesh, 28 | const std::shared_ptr &material, int subMesh) 29 | { 30 | this->node = node; 31 | this->mesh = mesh; 32 | this->material = material; 33 | this->subMesh = subMesh; 34 | } 35 | }; 36 | 37 | class FURY_API RenderQuery 38 | { 39 | public: 40 | 41 | typedef std::shared_ptr Ptr; 42 | 43 | static Ptr Create(); 44 | 45 | std::vector opaqueUnits; 46 | 47 | std::vector transparentUnits; 48 | 49 | std::vector> renderableNodes; 50 | 51 | std::vector> lightNodes; 52 | 53 | void AddRenderable(const std::shared_ptr &node); 54 | 55 | void AddLight(const std::shared_ptr &node); 56 | 57 | void Sort(Vector4 camPos); 58 | 59 | void Clear(); 60 | }; 61 | } 62 | 63 | #endif // _FURY_RENDERQUERY_H_ 64 | -------------------------------------------------------------------------------- /engine/Fury/RenderUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_RENDER_UTIL_H_ 2 | #define _FURY_RENDER_UTIL_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "Fury/ArrayBuffers.h" 11 | #include "Fury/Color.h" 12 | #include "Fury/Singleton.h" 13 | #include "Fury/Signal.h" 14 | #include "Fury/EnumUtil.h" 15 | #include "Fury/Pass.h" 16 | #include "Fury/Matrix4.h" 17 | 18 | namespace fury 19 | { 20 | class Mesh; 21 | 22 | class BoxBounds; 23 | 24 | class Frustum; 25 | 26 | class SceneNode; 27 | 28 | class Shader; 29 | 30 | class Texture; 31 | 32 | class FURY_API RenderUtil final : public Singleton 33 | { 34 | public: 35 | 36 | typedef std::shared_ptr Ptr; 37 | 38 | private: 39 | 40 | std::shared_ptr m_DebugShader; 41 | 42 | std::shared_ptr m_BlitShader; 43 | 44 | std::shared_ptr m_BlitPass; 45 | 46 | unsigned int m_LineVAO = 0; 47 | 48 | unsigned int m_LineVBO = 0; 49 | 50 | unsigned int m_DrawCall = 0; 51 | 52 | unsigned int m_MeshCount = 0; 53 | 54 | unsigned int m_TriangleCount = 0; 55 | 56 | unsigned int m_SkinnedMeshCount = 0; 57 | 58 | unsigned int m_LightCount = 0; 59 | 60 | sf::Clock m_FrameClock; 61 | 62 | bool m_DrawingLine = false; 63 | 64 | bool m_DrawingMesh = false; 65 | 66 | public: 67 | 68 | Signal<>::Ptr OnBeginFrame = Signal<>::Create(); 69 | 70 | // frame time in ms 71 | Signal::Ptr OnEndFrame = Signal::Create(); 72 | 73 | RenderUtil(); 74 | 75 | virtual ~RenderUtil(); 76 | 77 | void Blit(const std::shared_ptr &src, const std::shared_ptr &dest, 78 | ClearMode clearMode = ClearMode::COLOR_DEPTH_STENCIL, 79 | BlendMode blendMode = BlendMode::REPLACE); 80 | 81 | void Blit(const std::shared_ptr &src, const std::shared_ptr &dest, 82 | const std::shared_ptr &shader, ClearMode clearMode = ClearMode::COLOR_DEPTH_STENCIL, 83 | BlendMode blendMode = BlendMode::REPLACE); 84 | 85 | void BeginDrawLines(const std::shared_ptr &camera); 86 | 87 | void DrawLines(const float* positions, unsigned int size, Color color, LineMode lineMode = LineMode::LINES); 88 | 89 | void DrawBoxBounds(const BoxBounds &aabb, Color color); 90 | 91 | void DrawFrustum(const Frustum &frustum, Color color); 92 | 93 | void EndDrawLines(); 94 | 95 | void BeginDrawMeshs(const std::shared_ptr &camera); 96 | 97 | void DrawMesh(const std::shared_ptr &mesh, const Matrix4 &worldMatrix, Color color); 98 | 99 | void EndDrawMeshes(); 100 | 101 | void BeginFrame(); 102 | 103 | void EndFrame(); 104 | 105 | void IncreaseDrawCall(unsigned int count = 1); 106 | 107 | unsigned int GetDrawCall(); 108 | 109 | void IncreaseMeshCount(unsigned int count = 1); 110 | 111 | unsigned int GetMeshCount(); 112 | 113 | void IncreaseTriangleCount(unsigned int count = 1); 114 | 115 | unsigned int GetTriangleCount(); 116 | 117 | void IncreaseSkinnedMeshCount(unsigned int count = 1); 118 | 119 | unsigned int GetSkinnedMeshCount(); 120 | 121 | void IncreaseLightCount(unsigned int count = 1); 122 | 123 | unsigned int GetLightCount(); 124 | }; 125 | } 126 | 127 | #endif // _FURY_RENDER_UTIL_H_ -------------------------------------------------------------------------------- /engine/Fury/Scene.cpp: -------------------------------------------------------------------------------- 1 | #include "Fury/Scene.h" 2 | #include "Fury/OcTree.h" 3 | #include "Fury/EntityManager.h" 4 | #include "Fury/SceneNode.h" 5 | #include "Fury/Log.h" 6 | #include "Fury/Material.h" 7 | #include "Fury/Mesh.h" 8 | 9 | namespace fury 10 | { 11 | Scene::Ptr Scene::Active = nullptr; 12 | 13 | std::string Scene::Path(const std::string &path) 14 | { 15 | if (Scene::Active != nullptr) 16 | return Scene::Active->GetWorkingDir() + path; 17 | else 18 | return path; 19 | } 20 | 21 | std::shared_ptr Scene::Manager() 22 | { 23 | ASSERT_MSG(Scene::Active != nullptr, "Scene::Active == nullptr"); 24 | return Scene::Active->GetEntityManager(); 25 | } 26 | 27 | Scene::Ptr Scene::Create(const std::string &name, const std::string &workingDir, const std::shared_ptr &sceneManager) 28 | { 29 | return std::make_shared(name, workingDir, sceneManager); 30 | } 31 | 32 | Scene::Scene(const std::string &name, const std::string &workingDir, const std::shared_ptr &sceneManager) : 33 | Entity(name), m_WorkingDir(workingDir) 34 | { 35 | m_TypeIndex = typeid(Scene); 36 | if (sceneManager == nullptr) 37 | m_SceneManager = OcTree::Create(Vector4(-1000), Vector4(1000), 2); 38 | else 39 | m_SceneManager = sceneManager; 40 | 41 | m_EntityManager = EntityManager::Create(); 42 | m_RootNode = SceneNode::Create("RootNode"); 43 | } 44 | 45 | Scene::~Scene() 46 | { 47 | FURYD << "Scene " << m_Name << " Destoried!"; 48 | Clear(); 49 | } 50 | 51 | void Scene::Clear() 52 | { 53 | m_EntityManager->RemoveAll(); 54 | m_SceneManager->Clear(); 55 | m_RootNode->RemoveAllChilds(); 56 | m_RootNode->RemoveAllComponents(); 57 | } 58 | 59 | bool Scene::Load(const void* wrapper, bool object) 60 | { 61 | Clear(); 62 | 63 | if (object && !IsObject(wrapper)) 64 | { 65 | FURYE << "Json node is not an object!"; 66 | return false; 67 | } 68 | 69 | if (!Entity::Load(wrapper, false)) 70 | return false; 71 | 72 | // load materials 73 | if (!LoadArray(wrapper, "materials", [&](const void* node) -> bool 74 | { 75 | auto material = Material::Create("temp"); 76 | if (!material->Load(node)) 77 | return false; 78 | 79 | m_EntityManager->Add(material); 80 | return true; 81 | })) 82 | { 83 | FURYE << "Error serializing materials!"; 84 | return false; 85 | } 86 | 87 | // load meshes 88 | if (!LoadArray(wrapper, "meshes", [&](const void* node) -> bool 89 | { 90 | auto mesh = Mesh::Create("temp"); 91 | if (!mesh->Load(node)) 92 | return false; 93 | 94 | m_EntityManager->Add(mesh); 95 | return true; 96 | })) 97 | { 98 | FURYE << "Error serializing meshes!"; 99 | return false; 100 | } 101 | 102 | // load nodes 103 | if (auto rootNodeWrapper = FindMember(wrapper, "nodes")) 104 | { 105 | if (!m_RootNode->Load(rootNodeWrapper)) 106 | return false; 107 | } 108 | else 109 | { 110 | FURYE << "root_node not found!"; 111 | return false; 112 | } 113 | 114 | // setup scene manager 115 | m_SceneManager->AddSceneNodeRecursively(m_RootNode); 116 | 117 | return true; 118 | } 119 | 120 | void Scene::Save(void* wrapper, bool object) 121 | { 122 | if (object) 123 | StartObject(wrapper); 124 | 125 | Entity::Save(wrapper, false); 126 | 127 | // save materials 128 | SaveKey(wrapper, "materials"); 129 | StartArray(wrapper); 130 | m_EntityManager->ForEach([&](const Material::Ptr &ptr) -> bool 131 | { 132 | ptr->Save(wrapper); 133 | return true; 134 | }); 135 | EndArray(wrapper); 136 | 137 | // save meshes 138 | SaveKey(wrapper, "meshes"); 139 | StartArray(wrapper); 140 | m_EntityManager->ForEach([&](const Mesh::Ptr &ptr) -> bool 141 | { 142 | ptr->Save(wrapper); 143 | return true; 144 | }); 145 | EndArray(wrapper); 146 | 147 | // save nodes 148 | SaveKey(wrapper, "nodes"); 149 | m_RootNode->Save(wrapper); 150 | 151 | if (object) 152 | EndObject(wrapper); 153 | } 154 | 155 | std::shared_ptr Scene::GetRootNode() const 156 | { 157 | return m_RootNode; 158 | } 159 | 160 | std::shared_ptr Scene::GetSceneManager() const 161 | { 162 | return m_SceneManager; 163 | } 164 | 165 | std::shared_ptr Scene::GetEntityManager() const 166 | { 167 | return m_EntityManager; 168 | } 169 | 170 | std::string Scene::GetWorkingDir() const 171 | { 172 | return m_WorkingDir; 173 | } 174 | 175 | void Scene::SetWorkingDir(const std::string &path) 176 | { 177 | m_WorkingDir = path; 178 | } 179 | } -------------------------------------------------------------------------------- /engine/Fury/Scene.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_SCENE_H_ 2 | #define _FURY_SCENE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Entity.h" 8 | 9 | namespace fury 10 | { 11 | class EntityManager; 12 | 13 | class SceneNode; 14 | 15 | class SceneManager; 16 | 17 | class Material; 18 | 19 | class Mesh; 20 | 21 | class FURY_API Scene : public Entity 22 | { 23 | public: 24 | 25 | typedef std::shared_ptr Ptr; 26 | 27 | static Ptr Active; 28 | 29 | static std::string Path(const std::string &path); 30 | 31 | static std::shared_ptr Manager(); 32 | 33 | static Ptr Create(const std::string &name, const std::string &workingDir, const std::shared_ptr &sceneManager = nullptr); 34 | 35 | protected: 36 | 37 | std::shared_ptr m_RootNode; 38 | 39 | std::shared_ptr m_SceneManager; 40 | 41 | std::shared_ptr m_EntityManager; 42 | 43 | std::string m_WorkingDir; 44 | 45 | public: 46 | 47 | Scene(const std::string &name, const std::string &workingDir, const std::shared_ptr &sceneManager = nullptr); 48 | 49 | ~Scene(); 50 | 51 | void Clear(); 52 | 53 | virtual bool Load(const void* wrapper, bool object = true) override; 54 | 55 | virtual void Save(void* wrapper, bool object = true) override; 56 | 57 | std::shared_ptr GetRootNode() const; 58 | 59 | std::shared_ptr GetSceneManager() const; 60 | 61 | std::shared_ptr GetEntityManager() const; 62 | 63 | // extra resources prepends this to filepath when loading. 64 | std::string GetWorkingDir() const; 65 | 66 | void SetWorkingDir(const std::string &path); 67 | 68 | }; 69 | } 70 | 71 | #endif // _FURY_SCENE_H_ -------------------------------------------------------------------------------- /engine/Fury/SceneManager.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_SCENE_MANAGER_H_ 2 | #define _FURY_SCENE_MANAGER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "Macros.h" 9 | 10 | namespace fury 11 | { 12 | class Collidable; 13 | 14 | class RenderQuery; 15 | 16 | class SceneNode; 17 | 18 | class FURY_API SceneManager 19 | { 20 | public: 21 | 22 | typedef std::shared_ptr Ptr; 23 | 24 | typedef std::vector> SceneNodes; 25 | 26 | typedef std::function&)> FilterFunc; 27 | 28 | public: 29 | 30 | virtual void AddSceneNode(const std::shared_ptr &sceneNode) = 0; 31 | 32 | virtual void AddSceneNodeRecursively(const std::shared_ptr &sceneNode) = 0; 33 | 34 | virtual void RemoveSceneNode(const std::shared_ptr &sceneNode) = 0; 35 | 36 | virtual void UpdateSceneNode(const std::shared_ptr &sceneNode) = 0; 37 | 38 | virtual void GetRenderQuery(const Collidable &collider, const std::shared_ptr &renderQuery, bool clear = true) const = 0; 39 | 40 | virtual void GetVisibleSceneNodes(const Collidable &collider, SceneNodes &visibleNodes, bool clear = true) const = 0; 41 | 42 | virtual void GetVisibleRenderables(const Collidable &collider, SceneNodes &renderables, bool clear = true) const = 0; 43 | 44 | virtual void GetVisibleShadowCasters(const Collidable &collider, SceneNodes &renderables, bool clear = true) const = 0; 45 | 46 | virtual void GetVisibleLights(const Collidable &collider, SceneNodes &lights, bool clear = true) const = 0; 47 | 48 | virtual void GetVisibleRenderableAndLights(const Collidable &collider, SceneNodes &renderables, SceneNodes &lights, bool clear = true) const = 0; 49 | 50 | virtual void WalkScene(const Collidable &collider, const FilterFunc &filterFunc) const = 0; 51 | 52 | virtual void Clear() = 0; 53 | }; 54 | } 55 | 56 | #endif // _FURY_SCENE_MANAGER_H_ -------------------------------------------------------------------------------- /engine/Fury/Serializable.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_SERIALIZEABLE_H_ 2 | #define _FURY_SERIALIZEABLE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Fury/Macros.h" 10 | #include "Fury/EntityManager.h" 11 | 12 | namespace fury 13 | { 14 | class BoxBounds; 15 | 16 | class Color; 17 | 18 | class Vector4; 19 | 20 | class Quaternion; 21 | 22 | class Matrix4; 23 | 24 | class FURY_API Serializable 25 | { 26 | public: 27 | 28 | typedef std::shared_ptr Ptr; 29 | 30 | // wrapper's type should be rapidjson::Value 31 | virtual bool Load(const void* wrapper, bool object = true) = 0; 32 | 33 | // wrapper's type should be rapidjson::Writer 34 | virtual void Save(void* wrapper, bool object = true) = 0; 35 | 36 | protected: 37 | 38 | static std::string GetValueType(const void* wrapper); 39 | 40 | static const void* FindMember(const void* wrapper, const std::string &name); 41 | 42 | static bool LoadMemberValue(const void* wrapper, const std::string &name, bool &value); 43 | 44 | static bool LoadMemberValue(const void* wrapper, const std::string &name, int &value); 45 | 46 | static bool LoadMemberValue(const void* wrapper, const std::string &name, unsigned int &value); 47 | 48 | static bool LoadMemberValue(const void* wrapper, const std::string &name, float &value); 49 | 50 | static bool LoadMemberValue(const void* wrapper, const std::string &name, std::string &value); 51 | 52 | static bool LoadMemberValue(const void* wrapper, const std::string &name, Color &color); 53 | 54 | static bool LoadMemberValue(const void* wrapper, const std::string &name, Vector4 &vector); 55 | 56 | static bool LoadMemberValue(const void* wrapper, const std::string &name, Quaternion &quaternion); 57 | 58 | static bool LoadMemberValue(const void* wrapper, const std::string &name, Matrix4 &matrix); 59 | 60 | static bool LoadMemberValue(const void* wrapper, const std::string &name, BoxBounds &aabb); 61 | 62 | static bool LoadValue(const void* wrapper, bool &value); 63 | 64 | static bool LoadValue(const void* wrapper, int &value); 65 | 66 | static bool LoadValue(const void* wrapper, unsigned int &value); 67 | 68 | static bool LoadValue(const void* wrapper, float &value); 69 | 70 | static bool LoadValue(const void* wrapper, std::string &value); 71 | 72 | static bool LoadArray(const void* wrapper, std::function walker); 73 | 74 | static bool LoadArray(const void* wrapper, const std::string &name, std::function walker); 75 | 76 | // uint, int, float, bool, string 77 | template 78 | static bool LoadArray(const void* wrapper, const std::string &name, std::vector &raw); 79 | 80 | // uint, int, float, bool, string 81 | template 82 | static bool LoadArray(const void* wrapper, std::vector &raw); 83 | 84 | static void SaveKey(void* wrapper, const std::string &key); 85 | 86 | static void SaveValue(void* wrapper, bool value); 87 | 88 | static void SaveValue(void* wrapper, int value); 89 | 90 | static void SaveValue(void* wrapper, unsigned int value); 91 | 92 | static void SaveValue(void* wrapper, float value); 93 | 94 | static void SaveValue(void* wrapper, const std::string &value); 95 | 96 | static void SaveValue(void* wrapper, const char *value); 97 | 98 | static void SaveValue(void* wrapper, const Color &color); 99 | 100 | static void SaveValue(void* wrapper, const Vector4 &vector); 101 | 102 | static void SaveValue(void* wrapper, const Quaternion &quaternion); 103 | 104 | static void SaveValue(void* wrapper, const Matrix4 &matrix); 105 | 106 | static void SaveValue(void* wrapper, const BoxBounds &aabb); 107 | 108 | static void SaveArray(void *wrapper, unsigned int count, std::function walker); 109 | 110 | template 111 | static void SaveArray(void *wrapper, const std::shared_ptr &ptr, 112 | std::function&)> walker) 113 | { 114 | StartArray(wrapper); 115 | 116 | auto end = ptr->End(); 117 | for (auto it = ptr->Begin(); it != end; ++it) 118 | walker(std::static_pointer_cast(it->second)); 119 | 120 | EndArray(wrapper); 121 | } 122 | 123 | template 124 | static void SaveArray(void *wrapper, Container &raw, std::function walker) 125 | { 126 | StartArray(wrapper); 127 | 128 | for (auto it = raw.begin(); it != raw.end(); ++it) 129 | walker(it); 130 | 131 | EndArray(wrapper); 132 | } 133 | 134 | // uint, int, float, bool, string 135 | template 136 | static void SaveArray(void *wrapper, std::vector &raw); 137 | 138 | static void StartObject(void* wrapper); 139 | 140 | static void EndObject(void* wrapper); 141 | 142 | static void StartArray(void* wrapper); 143 | 144 | static void EndArray(void* wrapper); 145 | 146 | static bool IsObject(const void* wrapper); 147 | 148 | static bool IsObject(const void* wrapper, const std::string &member); 149 | 150 | static bool IsArray(const void* wrapper); 151 | 152 | static bool IsArray(const void* wrapper, const std::string &member); 153 | }; 154 | } 155 | 156 | #endif // _FURY_SERIALIZEABLE_H_ -------------------------------------------------------------------------------- /engine/Fury/Shader.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_SHADER_H_ 2 | #define _FURY_SHADER_H_ 3 | 4 | #include 5 | 6 | #include "Fury/Entity.h" 7 | #include "Fury/EnumUtil.h" 8 | #include "Fury/Matrix4.h" 9 | 10 | namespace fury 11 | { 12 | class Material; 13 | 14 | class Mesh; 15 | 16 | class SceneNode; 17 | 18 | class Texture; 19 | 20 | // always bind shader first. then material and meshes. 21 | class FURY_API Shader : public Entity 22 | { 23 | public: 24 | 25 | typedef std::shared_ptr Ptr; 26 | 27 | static Ptr Create(const std::string &name, ShaderType type, unsigned int textureFlags = 0); 28 | 29 | protected: 30 | 31 | std::string m_FilePath; 32 | 33 | ShaderType m_Type; 34 | 35 | unsigned int m_TextureFlags; 36 | 37 | std::vector m_Defines; 38 | 39 | unsigned int m_Program = 0; 40 | 41 | unsigned int m_TextureID = 0; 42 | 43 | bool m_Dirty = true; 44 | 45 | bool m_UseGeomShader = false; 46 | 47 | public: 48 | 49 | Shader(const std::string &name, ShaderType type, unsigned int textureFlags = 0); 50 | 51 | virtual ~Shader(); 52 | 53 | virtual bool Load(const void* wrapper, bool object = true) override; 54 | 55 | virtual void Save(void* wrapper, bool object = true) override; 56 | 57 | unsigned int GetProgram() const; 58 | 59 | bool GetDirty() const; 60 | 61 | std::string GetFilePath() const; 62 | 63 | ShaderType GetType() const; 64 | 65 | unsigned int GetTextureFlags() const; 66 | 67 | void SetTextureFlags(unsigned int flags); 68 | 69 | void AddDefine(std::string define); 70 | 71 | bool LoadAndCompile(const std::string &shaderPath, bool useGeomShader = false); 72 | 73 | bool Compile(const std::string &vsData, const std::string &fsData, const std::string &gsData); 74 | 75 | void DeleteProgram(); 76 | 77 | void Bind(); 78 | 79 | void BindCamera(const std::shared_ptr &camNode); 80 | 81 | void BindLight(const std::shared_ptr &lightNode); 82 | 83 | // bind texture to 1st texture 84 | void BindTexture(const std::shared_ptr &texture); 85 | 86 | // bind texture to 1st texture 87 | void BindTexture(size_t textureId, TextureType type); 88 | 89 | void BindTexture(const std::string &name, const std::shared_ptr &texture); 90 | 91 | void BindTexture(const std::string &name, size_t textureId, TextureType type); 92 | 93 | void BindMaterial(const std::shared_ptr &material); 94 | 95 | void BindMesh(const std::shared_ptr &mesh); 96 | 97 | void BindSubMesh(const std::shared_ptr &mesh, unsigned int index); 98 | 99 | void BindMatrix(const std::string &name, const Matrix4 &matrix); 100 | 101 | void BindMatrix(const std::string &name, const float *raw); 102 | 103 | void BindMatrices(const std::string &name, int count, const float *raw); 104 | 105 | void BindMatrices(const std::string &name, int count, const Matrix4 *matrices); 106 | 107 | void BindFloat(const std::string &name, float v0); 108 | 109 | void BindFloat(const std::string &name, float v0, float v1); 110 | 111 | void BindFloat(const std::string &name, float v0, float v1, float v2); 112 | 113 | void BindFloat(const std::string &name, float v0, float v1, float v2, float v3); 114 | 115 | void BindFloat(const std::string &name, int size, int count, const float *value); 116 | 117 | void BindInt(const std::string &name, int v0); 118 | 119 | void BindInt(const std::string &name, int v0, int v1); 120 | 121 | void BindInt(const std::string &name, int v0, int v1, int v2); 122 | 123 | void BindInt(const std::string &name, int v0, int v1, int v2, int v3); 124 | 125 | void BindInt(const std::string &name, int size, int count, const int *value); 126 | 127 | void BindUInt(const std::string &name, unsigned int v0); 128 | 129 | void BindUInt(const std::string &name, unsigned int v0, unsigned int v1); 130 | 131 | void BindUInt(const std::string &name, unsigned int v0, unsigned int v1, unsigned int v2); 132 | 133 | void BindUInt(const std::string &name, unsigned int v0, unsigned int v1, unsigned int v2, unsigned int v3); 134 | 135 | void BindUInt(const std::string &name, int size, int count, const unsigned int *value); 136 | 137 | void UnBind(); 138 | 139 | protected: 140 | 141 | void BindMeshData(const std::shared_ptr &mesh); 142 | 143 | int GetUniformLocation(const std::string &name) const; 144 | 145 | void GetVersionInfo(const std::string &source, std::string &versionStr, std::string &mainStr); 146 | 147 | }; 148 | } 149 | 150 | #endif // _FURY_SHADER_H_ -------------------------------------------------------------------------------- /engine/Fury/Signal.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_SIGNAL_H_ 2 | #define _FURY_SIGNAL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "Fury/TypeComparable.h" 13 | 14 | namespace fury 15 | { 16 | // thread safe 17 | template 18 | class Signal : public TypeComparable 19 | { 20 | public: 21 | 22 | typedef std::shared_ptr> Ptr; 23 | 24 | typedef std::function CallbackFunc; 25 | 26 | typedef std::pair, CallbackFunc> CallbackPair; 27 | 28 | static Ptr Create() 29 | { 30 | return std::make_shared>(); 31 | } 32 | 33 | private: 34 | 35 | std::mutex m_LinkMapMutex; 36 | 37 | std::mutex m_KeyGenMutex; 38 | 39 | std::unordered_map m_LinkMap; 40 | 41 | std::shared_ptr m_DefaultOwner; 42 | 43 | std::stack m_KeyStack; 44 | 45 | size_t m_CurrentKey; 46 | 47 | std::type_index m_TypeIndex; 48 | 49 | public: 50 | 51 | Signal() : m_TypeIndex(typeid(Signal)) 52 | { 53 | m_DefaultOwner = std::static_pointer_cast(std::make_shared(true)); 54 | } 55 | 56 | virtual std::type_index GetTypeIndex() const 57 | { 58 | return m_TypeIndex; 59 | } 60 | 61 | size_t GenKey() 62 | { 63 | std::lock_guard lock(m_KeyGenMutex); 64 | 65 | if (m_KeyStack.empty()) 66 | { 67 | return m_CurrentKey++; 68 | } 69 | else 70 | { 71 | auto key = m_KeyStack.top(); 72 | m_KeyStack.pop(); 73 | return key; 74 | } 75 | } 76 | 77 | size_t Connect(void(*f)(Args...)) 78 | { 79 | auto key = GenKey(); 80 | std::lock_guard lock(m_LinkMapMutex); 81 | m_LinkMap.emplace(std::make_pair(key, 82 | std::make_pair, CallbackFunc>(m_DefaultOwner, f))); 83 | return key; 84 | } 85 | 86 | template 87 | size_t Connect(const std::shared_ptr &reciver, void(Reciver::*f)(Args ...)) 88 | { 89 | auto key = GenKey(); 90 | auto rawPtr = reciver.get(); 91 | CallbackFunc forward = [rawPtr, f](Args&&... args) 92 | { 93 | (rawPtr->*f)(std::forward(args)...); 94 | }; 95 | 96 | std::lock_guard lock(m_LinkMapMutex); 97 | 98 | m_LinkMap.emplace(std::make_pair(key, 99 | std::make_pair(std::static_pointer_cast(reciver), forward))); 100 | 101 | return key; 102 | } 103 | 104 | bool Disconnect(size_t key) 105 | { 106 | std::lock_guard lockLinkMap(m_LinkMapMutex); 107 | 108 | auto it = m_LinkMap.find(key); 109 | if (it != m_LinkMap.end()) 110 | { 111 | std::lock_guard lockKeyGen(m_KeyGenMutex); 112 | m_KeyStack.push(key); 113 | m_LinkMap.erase(it); 114 | return true; 115 | } 116 | else 117 | { 118 | return false; 119 | } 120 | } 121 | 122 | void Clear() 123 | { 124 | { 125 | std::lock_guard lockKeyGen(m_KeyGenMutex); 126 | while (!m_KeyStack.empty()) 127 | m_KeyStack.pop(); 128 | } 129 | 130 | m_CurrentKey = 0; 131 | std::lock_guard lockLinkMap(m_LinkMapMutex); 132 | m_LinkMap.clear(); 133 | } 134 | 135 | void Emit(Args&&... args) 136 | { 137 | std::lock_guard lock(m_LinkMapMutex); 138 | 139 | std::vector::iterator> tobeRemoved; 140 | 141 | for (auto it = m_LinkMap.begin(); it != m_LinkMap.end(); ++it) 142 | { 143 | if (it->second.first.expired()) 144 | tobeRemoved.push_back(it); 145 | else 146 | it->second.second(std::forward(args)...); 147 | } 148 | 149 | for (auto it = tobeRemoved.begin(); it != tobeRemoved.end(); ++it) 150 | m_LinkMap.erase(*it); 151 | } 152 | }; 153 | } 154 | 155 | #endif // _FURY_SIGNAL_H_ -------------------------------------------------------------------------------- /engine/Fury/Singleton.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_SINGLETON_H_ 2 | #define _FURY_SINGLETON_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Macros.h" 8 | 9 | namespace fury 10 | { 11 | template 12 | class Singleton 13 | { 14 | protected: 15 | 16 | static std::shared_ptr m_Instance; 17 | 18 | public: 19 | 20 | // this returns reference to current instance. 21 | // so you can call Instance().reset() to destory static instance. 22 | inline static std::shared_ptr &Instance() 23 | { 24 | ASSERT_MSG(m_Instance, "Singleton instance doesn't exist!"); 25 | return m_Instance; 26 | } 27 | 28 | // make sure your singleton initializes later than log singleton. 29 | inline static std::shared_ptr &Initialize(Args&&... args) 30 | { 31 | ASSERT_MSG(!m_Instance, "Singleton instance already exist!"); 32 | m_Instance = std::make_shared(std::forward(args)...); 33 | return m_Instance; 34 | } 35 | 36 | // don't do logs in singleton's destructor 37 | // because when destructing, Log's instance might be destoried already. 38 | virtual ~Singleton() 39 | { 40 | m_Instance = nullptr; 41 | } 42 | }; 43 | 44 | template 45 | std::shared_ptr Singleton::m_Instance = nullptr; 46 | } 47 | 48 | #endif // _FURY_SINGLETON_H_ -------------------------------------------------------------------------------- /engine/Fury/SphereBounds.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "Fury/BoxBounds.h" 4 | #include "Fury/SphereBounds.h" 5 | 6 | namespace fury 7 | { 8 | SphereBounds::SphereBounds() 9 | { 10 | Zero(); 11 | } 12 | 13 | SphereBounds::SphereBounds(Vector4 center, float radius) : m_Dirty(false) 14 | { 15 | SetCenterRadius(center, radius); 16 | } 17 | 18 | void SphereBounds::SetCenterRadius(Vector4 center, float radius) 19 | { 20 | m_Center = center; 21 | m_Radius = radius; 22 | } 23 | 24 | void SphereBounds::Zero() 25 | { 26 | m_Center.Zero(); 27 | m_Radius = 0.0f; 28 | } 29 | 30 | void SphereBounds::SetInfinite(bool value) 31 | { 32 | m_Infinite = value; 33 | if (m_Infinite) 34 | m_Radius = std::numeric_limits::max(); 35 | } 36 | 37 | bool SphereBounds::GetInfinite() const 38 | { 39 | return m_Infinite; 40 | } 41 | 42 | Side SphereBounds::IsInside(Vector4 point) const 43 | { 44 | if (m_Infinite) return Side::IN; 45 | 46 | float distance = (m_Center - point).Length(); 47 | if (distance < m_Radius) 48 | return Side::IN; 49 | else if (distance > m_Radius) 50 | return Side::OUT; 51 | else 52 | return Side::STRADDLE; 53 | } 54 | 55 | Side SphereBounds::IsInside(const BoxBounds &aabb) const 56 | { 57 | if (m_Infinite || aabb.GetInfinite()) return Side::IN; 58 | 59 | float radius2 = m_Radius * m_Radius; 60 | if ((m_Center - aabb.FarestPoint(m_Center)).SquareLength() < radius2) 61 | return Side::IN; 62 | else if ((m_Center - aabb.ClosestPoint(m_Center)).SquareLength() <= radius2) 63 | return Side::STRADDLE; 64 | else 65 | return Side::OUT; 66 | } 67 | 68 | Side SphereBounds::IsInside(const SphereBounds &bsphere) const 69 | { 70 | if (m_Infinite || bsphere.GetInfinite()) return Side::IN; 71 | 72 | float distance = (m_Center - bsphere.GetCenter()).Length(); 73 | if (distance >= m_Radius + bsphere.GetRadius()) 74 | return Side::OUT; 75 | else if (distance + bsphere.GetRadius() < m_Radius) 76 | return Side::IN; 77 | else 78 | return Side::STRADDLE; 79 | } 80 | 81 | bool SphereBounds::IsInsideFast(Vector4 point) const 82 | { 83 | if (m_Infinite) return true; 84 | return (m_Center - point).SquareLength() <= m_Radius * m_Radius; 85 | } 86 | 87 | bool SphereBounds::IsInsideFast(const BoxBounds &aabb) const 88 | { 89 | if (m_Infinite || aabb.GetInfinite()) return true; 90 | return (m_Center - aabb.ClosestPoint(m_Center)).SquareLength() <= m_Radius * m_Radius; 91 | } 92 | 93 | bool SphereBounds::IsInsideFast(const SphereBounds &bsphere) const 94 | { 95 | if (m_Infinite || bsphere.GetInfinite()) return true; 96 | const float radius = m_Radius + bsphere.m_Radius; 97 | return (m_Center - bsphere.GetCenter()).SquareLength() <= radius * radius; 98 | } 99 | 100 | void SphereBounds::Encapsulate(const BoxBounds &aabb) 101 | { 102 | if (m_Infinite || aabb.GetInfinite()) 103 | { 104 | SetInfinite(true); 105 | return; 106 | } 107 | 108 | float radius = aabb.GetExtents().Length(); 109 | 110 | if (m_Dirty) 111 | { 112 | m_Dirty = false; 113 | SetCenterRadius(aabb.GetCenter(), radius); 114 | } 115 | else 116 | { 117 | m_Radius = (m_Center - aabb.GetCenter()).Length() + radius; 118 | } 119 | } 120 | 121 | void SphereBounds::Encapsulate(const SphereBounds &bsphere) 122 | { 123 | if (m_Infinite || bsphere.GetInfinite()) 124 | { 125 | SetInfinite(true); 126 | return; 127 | } 128 | 129 | if (m_Dirty) 130 | { 131 | m_Dirty = false; 132 | SetCenterRadius(bsphere.GetCenter(), bsphere.GetRadius()); 133 | } 134 | else 135 | { 136 | m_Radius = (m_Center - bsphere.GetCenter()).Length() + bsphere.GetRadius(); 137 | } 138 | } 139 | 140 | void SphereBounds::Encapsulate(Vector4 point) 141 | { 142 | if (m_Infinite) return; 143 | 144 | if (m_Dirty) 145 | { 146 | m_Dirty = false; 147 | SetCenterRadius(point, 0.0f); 148 | } 149 | else 150 | { 151 | m_Radius = (m_Center - point).Length(); 152 | } 153 | } 154 | 155 | float SphereBounds::GetDistance(Vector4 point) const 156 | { 157 | float distance = (m_Center - point).Length(); 158 | return distance > m_Radius ? 0.0f : distance - m_Radius; 159 | } 160 | 161 | Vector4 SphereBounds::GetCenter() const 162 | { 163 | return m_Center; 164 | } 165 | 166 | float SphereBounds::GetRadius() const 167 | { 168 | return m_Radius; 169 | } 170 | 171 | bool SphereBounds::GetDirty() const 172 | { 173 | return m_Dirty; 174 | } 175 | 176 | void SphereBounds::SetDirty(bool dirty) 177 | { 178 | m_Dirty = dirty; 179 | } 180 | 181 | SphereBounds &SphereBounds::operator = (const SphereBounds &data) 182 | { 183 | if (data.GetInfinite()) 184 | SetInfinite(true); 185 | else 186 | SetCenterRadius(data.GetCenter(), data.GetRadius()); 187 | 188 | return *this; 189 | } 190 | 191 | bool SphereBounds::operator == (const SphereBounds &data) const 192 | { 193 | return m_Radius == data.GetRadius() && m_Center == data.GetCenter(); 194 | } 195 | 196 | bool SphereBounds::operator != (const SphereBounds &data) const 197 | { 198 | return m_Radius != data.GetRadius() || m_Center != data.GetCenter(); 199 | } 200 | } -------------------------------------------------------------------------------- /engine/Fury/SphereBounds.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_SPHEREBOUNDS_H_ 2 | #define _FURY_SPHEREBOUNDS_H_ 3 | 4 | #include "Fury/Collidable.h" 5 | #include "Fury/Vector4.h" 6 | 7 | namespace fury 8 | { 9 | class BoxBounds; 10 | 11 | class FURY_API SphereBounds : public Collidable 12 | { 13 | protected: 14 | 15 | Vector4 m_Center; 16 | 17 | float m_Radius; 18 | 19 | bool m_Infinite = false; 20 | 21 | bool m_Dirty = false; 22 | 23 | public: 24 | 25 | SphereBounds(); 26 | 27 | SphereBounds(Vector4 center, float radius); 28 | 29 | void SetCenterRadius(Vector4 center, float radius); 30 | 31 | void Zero(); 32 | 33 | void SetInfinite(bool value); 34 | 35 | bool GetInfinite() const; 36 | 37 | virtual Side IsInside(Vector4 point) const; 38 | 39 | virtual Side IsInside(const BoxBounds &aabb) const; 40 | 41 | virtual Side IsInside(const SphereBounds &bsphere) const; 42 | 43 | virtual bool IsInsideFast(Vector4 point) const; 44 | 45 | virtual bool IsInsideFast(const BoxBounds &aabb) const; 46 | 47 | virtual bool IsInsideFast(const SphereBounds &bsphere) const; 48 | 49 | // grow to include another aabb. 50 | void Encapsulate(const BoxBounds &aabb); 51 | 52 | // grow to include another bsphere. 53 | void Encapsulate(const SphereBounds &bsphere); 54 | 55 | // grow to include a point. 56 | void Encapsulate(Vector4 point); 57 | 58 | // get the shortest distance between point to aabb. 59 | // if the point is inside the aabb, 0 will be returned. 60 | float GetDistance(Vector4 point) const; 61 | 62 | Vector4 GetCenter() const; 63 | 64 | float GetRadius() const; 65 | 66 | bool GetDirty() const; 67 | 68 | // this will change Encapsulate's first-time behaviour. 69 | void SetDirty(bool dirty); 70 | 71 | SphereBounds &operator = (const SphereBounds &data); 72 | 73 | bool operator == (const SphereBounds &data) const; 74 | 75 | bool operator != (const SphereBounds &data) const; 76 | 77 | }; 78 | } 79 | 80 | #endif // _FURY_SPHEREBOUNDS_H_ -------------------------------------------------------------------------------- /engine/Fury/Texture.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_TEXTURE_H_ 2 | #define _FURY_TEXTURE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "Fury/Buffer.h" 8 | #include "Fury/Color.h" 9 | #include "Fury/Entity.h" 10 | #include "Fury/EnumUtil.h" 11 | #include "Fury/Serializable.h" 12 | 13 | namespace fury 14 | { 15 | // note that if you don't create texture from Texture's static creators. 16 | // then the new texture is not added to BufferManager, add that texture if you need. 17 | class FURY_API Texture : public Entity, public Buffer 18 | { 19 | protected: 20 | 21 | static std::unordered_map>> m_TexturePool; 22 | 23 | static std::string GetKeyFromParams(int width, int height, int depth, TextureFormat format, TextureType type); 24 | 25 | static std::string GetKeyFromPtr(const std::shared_ptr &ptr); 26 | 27 | public: 28 | 29 | typedef std::shared_ptr Ptr; 30 | 31 | static Ptr Create(const std::string &name); 32 | 33 | // create new or reuse texture from pool. textures are named like 512x512xrgba8x2d. 34 | static Ptr GetTemporary(int width, int height, int depth, TextureFormat format, TextureType type = TextureType::TEXTURE_2D); 35 | 36 | // collect texture to pool for reuse. 37 | static void ReleaseTemporary(const std::shared_ptr &ptr); 38 | 39 | // delete and release all textures from pool. 40 | static void ReleaseTempories(); 41 | 42 | protected: 43 | 44 | TextureFormat m_Format = TextureFormat::UNKNOW; 45 | 46 | TextureType m_Type = TextureType::TEXTURE_2D; 47 | 48 | unsigned int m_TypeUint = 0; 49 | 50 | FilterMode m_FilterMode = FilterMode::LINEAR; 51 | 52 | WrapMode m_WrapMode = WrapMode::REPEAT; 53 | 54 | Color m_BorderColor; 55 | 56 | bool m_Mipmap = false; 57 | 58 | int m_Width = 0; 59 | 60 | int m_Height = 0; 61 | 62 | int m_Depth = 0; 63 | 64 | unsigned int m_ID = 0; 65 | 66 | std::string m_FilePath; 67 | 68 | public: 69 | 70 | Texture(const std::string &name); 71 | 72 | virtual ~Texture(); 73 | 74 | virtual bool Load(const void* wrapper, bool object = true) override; 75 | 76 | virtual void Save(void* wrapper, bool object = true) override; 77 | 78 | void CreateFromImage(const std::string &filePath, bool srgb, bool mipMap); 79 | 80 | void CreateEmpty(int width, int height, int depth, TextureFormat format = TextureFormat::RGBA8, TextureType type = TextureType::TEXTURE_2D, bool mipMap = false); 81 | 82 | void SetPixels(const void* pixels); 83 | 84 | virtual void UpdateBuffer() override; 85 | 86 | virtual void DeleteBuffer() override; 87 | 88 | bool IsSRGB() const; 89 | 90 | TextureFormat GetFormat() const; 91 | 92 | TextureType GetType() const; 93 | 94 | unsigned int GetTypeUint() const; 95 | 96 | FilterMode GetFilterMode() const; 97 | 98 | void SetFilterMode(FilterMode mode); 99 | 100 | WrapMode GetWrapMode() const; 101 | 102 | void SetWrapMode(WrapMode mode); 103 | 104 | Color GetBorderColor() const; 105 | 106 | void SetBorderColor(Color color); 107 | 108 | void GenerateMipMap(); 109 | 110 | bool GetMipmap() const; 111 | 112 | int GetWidth() const; 113 | 114 | int GetHeight() const; 115 | 116 | int GetDepth() const; 117 | 118 | unsigned int GetID() const; 119 | 120 | std::string GetFilePath() const; 121 | 122 | protected: 123 | 124 | void IncreaseMemory(); 125 | 126 | void DecreaseMemory(); 127 | }; 128 | } 129 | 130 | #endif // _FURY_TEXTURE_H_ -------------------------------------------------------------------------------- /engine/Fury/ThreadUtil.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "Fury/Log.h" 5 | #include "Fury/ThreadUtil.h" 6 | 7 | namespace fury 8 | { 9 | std::thread::id ThreadUtil::m_MainThreadId; 10 | 11 | size_t ThreadUtil::m_TaskKey = 0; 12 | 13 | ThreadUtil::ThreadUtil(unsigned int numThreads) 14 | : m_Stop(false) 15 | { 16 | unsigned int maxThreads = std::thread::hardware_concurrency(); 17 | if (numThreads > maxThreads) 18 | { 19 | numThreads = maxThreads / 2; 20 | FURYW << "Hardware supports " << maxThreads << " threads at most!"; 21 | } 22 | 23 | for (unsigned int i = 0; i < numThreads; i++) 24 | { 25 | m_Workers.emplace_back([this] 26 | { 27 | while (true) 28 | { 29 | std::function task; 30 | 31 | { 32 | std::unique_lock lock(this->m_QueueMutex); 33 | this->m_Condiction.wait(lock, [this] 34 | { 35 | return this->m_Stop || !this->m_Tasks.empty(); 36 | }); 37 | 38 | if (this->m_Stop && this->m_Tasks.empty()) 39 | return; 40 | 41 | task = std::move(this->m_Tasks.front()); 42 | this->m_Tasks.pop(); 43 | } 44 | 45 | task(); 46 | } 47 | }); 48 | } 49 | } 50 | 51 | ThreadUtil::~ThreadUtil() 52 | { 53 | { 54 | std::unique_lock lock(m_QueueMutex); 55 | m_Stop = true; 56 | m_TaskStates.clear(); 57 | } 58 | 59 | m_Condiction.notify_all(); 60 | for (std::thread &worker : m_Workers) 61 | worker.join(); 62 | } 63 | 64 | size_t ThreadUtil::Enqueue(std::function task, std::function callback, std::function progressChanged) 65 | { 66 | std::unique_lock lock(m_QueueMutex); 67 | 68 | // don't allow enqueueing after stopping the pool 69 | if (m_Stop) 70 | throw std::runtime_error("Enqueue on stopped ThreadPool"); 71 | 72 | size_t key = m_TaskKey++; 73 | auto state = std::make_shared(key, nullptr); 74 | state->callback = callback; 75 | state->progressChanged = progressChanged; 76 | 77 | m_Tasks.emplace([task, state]() 78 | { 79 | task(state->progress); 80 | state->finished = true; 81 | }); 82 | 83 | m_TaskStates.emplace(key, state); 84 | m_Condiction.notify_one(); 85 | return key; 86 | } 87 | 88 | void ThreadUtil::Update() 89 | { 90 | std::unique_lock lock(m_QueueMutex); 91 | 92 | std::list finishedTasks; 93 | for (auto &pair : m_TaskStates) 94 | { 95 | auto id = pair.first; 96 | auto &state = pair.second; 97 | 98 | if (state->progressChanged) 99 | { 100 | auto it = m_TaskProgresses.find(id); 101 | if (it == m_TaskProgresses.end()) 102 | { 103 | m_TaskProgresses.emplace(id, state->progress); 104 | state->progressChanged(state->progress); 105 | } 106 | else if (it->second != state->progress) 107 | { 108 | m_TaskProgresses[id] = state->progress; 109 | state->progressChanged(state->progress); 110 | } 111 | } 112 | 113 | if (state->finished) 114 | finishedTasks.emplace_back(id); 115 | } 116 | 117 | for (auto &id : finishedTasks) 118 | { 119 | auto state = m_TaskStates[id]; 120 | m_TaskStates.erase(id); 121 | m_TaskProgresses.erase(id); 122 | if (state->callback) 123 | state->callback(); 124 | } 125 | } 126 | 127 | size_t ThreadUtil::GetWorkerCount() 128 | { 129 | return m_Workers.size(); 130 | } 131 | 132 | void ThreadUtil::SetMainThread() 133 | { 134 | m_MainThreadId = std::this_thread::get_id(); 135 | } 136 | 137 | bool ThreadUtil::IsMainThread() 138 | { 139 | return std::this_thread::get_id() == m_MainThreadId; 140 | } 141 | } -------------------------------------------------------------------------------- /engine/Fury/ThreadUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_THREAD_UTIL_H_ 2 | #define _FURY_THREAD_UTIL_H_ 3 | 4 | // Implimentation refers to: https://github.com/progschj/ThreadPool 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "Fury/Singleton.h" 16 | 17 | namespace fury 18 | { 19 | class FURY_API ThreadUtil : public Singleton 20 | { 21 | public: 22 | 23 | typedef std::shared_ptr Ptr; 24 | 25 | protected: 26 | 27 | class TaskState 28 | { 29 | public: 30 | 31 | size_t id = 0; 32 | 33 | int progress = 0; 34 | 35 | bool finished = false; 36 | 37 | std::shared_ptr data; 38 | 39 | std::function callback; 40 | 41 | std::function progressChanged; 42 | 43 | TaskState(size_t id, std::shared_ptr data) 44 | : id(id), data(data) {} 45 | }; 46 | 47 | static std::thread::id m_MainThreadId; 48 | 49 | static size_t m_TaskKey; 50 | 51 | std::unordered_map> m_TaskStates; 52 | 53 | std::unordered_map m_TaskProgresses; 54 | 55 | std::queue> m_Tasks; 56 | 57 | std::vector m_Workers; 58 | 59 | std::mutex m_QueueMutex; 60 | 61 | std::condition_variable m_Condiction; 62 | 63 | bool m_Stop; 64 | 65 | public: 66 | 67 | ThreadUtil(unsigned int numThreads); 68 | 69 | ~ThreadUtil(); 70 | 71 | size_t Enqueue(std::function task, std::function callback, std::function progressChanged = nullptr); 72 | 73 | template 74 | size_t Enqueue(std::function(int&)> task, std::function)> callback, 75 | std::function progressChanged = nullptr) 76 | { 77 | std::unique_lock lock(m_QueueMutex); 78 | 79 | // don't allow enqueueing after stopping the pool 80 | if (m_Stop) 81 | throw std::runtime_error("Enqueue on stopped ThreadPool"); 82 | 83 | size_t key = m_TaskKey++; 84 | auto state = std::make_shared(key, nullptr); 85 | state->callback = [callback, state] 86 | { 87 | callback(std::static_pointer_cast(state->data)); 88 | }; 89 | state->progressChanged = progressChanged; 90 | 91 | m_Tasks.emplace([task, state]() 92 | { 93 | state->data = task(state->progress); 94 | state->finished = true; 95 | }); 96 | 97 | m_TaskStates.emplace(key, state); 98 | m_Condiction.notify_one(); 99 | return key; 100 | } 101 | 102 | void Update(); 103 | 104 | size_t GetWorkerCount(); 105 | 106 | void SetMainThread(); 107 | 108 | bool IsMainThread(); 109 | }; 110 | } 111 | 112 | #endif // _FURY_THREAD_UTIL_H_ -------------------------------------------------------------------------------- /engine/Fury/Transform.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/engine/Fury/Transform.cpp -------------------------------------------------------------------------------- /engine/Fury/Transform.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_TRANSFORM_H_ 2 | #define _FURY_TRANSFORM_H_ 3 | 4 | #include "Fury/Quaternion.h" 5 | #include "Fury/Matrix4.h" 6 | #include "Fury/Vector4.h" 7 | #include "Fury/Component.h" 8 | 9 | namespace fury 10 | { 11 | class FURY_API Transform : public Component 12 | { 13 | public: 14 | 15 | typedef std::shared_ptr Ptr; 16 | 17 | static Ptr Create(); 18 | 19 | static Ptr Create(Vector4 position, Quaternion rotation, Vector4 scale); 20 | 21 | protected: 22 | 23 | Vector4 m_PrePosition, m_Position, m_PostPosition, m_WorldPosition; 24 | 25 | Quaternion m_PreRotation, m_Rotation, m_PostRotation, m_WorldRotation; 26 | 27 | Vector4 m_PreScale, m_Scale, m_PostScale, m_WorldScale; 28 | 29 | Matrix4 m_Matrix; 30 | 31 | float m_Dt = 0.0f; 32 | 33 | bool m_Dirty = true; 34 | 35 | public: 36 | 37 | Transform(); 38 | 39 | Transform(Vector4 position, Quaternion rotation, Vector4 scale); 40 | 41 | Component::Ptr Clone() const override; 42 | 43 | float GetDeltaTime() const; 44 | 45 | // this'll recalculate output matrices. 46 | void SetDeltaTime(float dt); 47 | 48 | // sync pre and post transforms. 49 | void SyncTransforms(); 50 | 51 | void SyncTransforms(const std::shared_ptr &sceneNode); 52 | 53 | void SetPreTransforms(Vector4 position, Quaternion rotation, Vector4 scale); 54 | 55 | void SetPostTransforms(Vector4 position, Quaternion rotation, Vector4 scale); 56 | 57 | // set 'initial' position 58 | void SetPrePosition(Vector4 position); 59 | 60 | Vector4 GetPrePosition() const; 61 | 62 | // set 'target' position 63 | void SetPostPosition(Vector4 position); 64 | 65 | Vector4 GetPostPosition() const; 66 | 67 | // set both 'initial' and 'target' position. 68 | void SetPosition(Vector4 position); 69 | 70 | // returns current position 71 | Vector4 GetPosition() const; 72 | 73 | // set 'initial' rotation 74 | void SetPreRotation(Quaternion rotation); 75 | 76 | Quaternion GetPreRotation() const; 77 | 78 | // set 'target' rotation 79 | void SetPostRotation(Quaternion rotation); 80 | 81 | Quaternion GetPostRotation() const; 82 | 83 | // set both 'initial' and 'target' rotation. 84 | void SetRotation(Quaternion rotation); 85 | 86 | // get current rotation 87 | Quaternion GetRotation() const; 88 | 89 | // set 'initial' scale 90 | void SetPreScale(Vector4 scale); 91 | 92 | Vector4 GetPreScale() const; 93 | 94 | // set 'target' scale 95 | void SetPostScale(Vector4 scale); 96 | 97 | Vector4 GetPostScale() const; 98 | 99 | // set both 'initial' and 'target' scale. 100 | void SetScale(Vector4 scale); 101 | 102 | // get current scale 103 | Vector4 GetScale() const; 104 | 105 | Matrix4 GetMatrix() const; 106 | 107 | protected: 108 | 109 | virtual void OnAttaching(const std::shared_ptr &node) override; 110 | }; 111 | 112 | } 113 | 114 | #endif // _FURY_TRANSFORM_H_ -------------------------------------------------------------------------------- /engine/Fury/TypeComparable.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_TYPE_COMPARABLE_H_ 2 | #define _FURY_TYPE_COMPARABLE_H_ 3 | 4 | #include 5 | 6 | #include "Macros.h" 7 | 8 | namespace fury 9 | { 10 | class FURY_API TypeComparable 11 | { 12 | public: 13 | 14 | virtual std::type_index GetTypeIndex() const = 0; 15 | }; 16 | } 17 | 18 | #endif // _FURY_TYPE_COMPARABLE_H_ -------------------------------------------------------------------------------- /engine/Fury/Uniform.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_UNIFORM_H_ 2 | #define _FURY_UNIFORM_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Fury/TypeComparable.h" 10 | #include "Fury/Serializable.h" 11 | 12 | namespace fury 13 | { 14 | class FURY_API UniformBase : public TypeComparable, public Serializable 15 | { 16 | public: 17 | 18 | typedef std::shared_ptr Ptr; 19 | 20 | UniformBase(); 21 | 22 | virtual void Bind(unsigned int program, const std::string &name) = 0; 23 | 24 | virtual bool Load(const void* wrapper, bool object = true) override = 0; 25 | 26 | virtual void Save(void* wrapper, bool object = true) override = 0; 27 | 28 | virtual std::type_index GetTypeIndex() const override; 29 | 30 | unsigned int GetSize() const; 31 | 32 | protected: 33 | 34 | std::type_index m_TypeIndex; 35 | 36 | unsigned int m_Size; 37 | 38 | static const std::unordered_map m_UniformTypeMap; 39 | }; 40 | 41 | template 42 | class FURY_API Uniform : public UniformBase 43 | { 44 | protected: 45 | 46 | Datatype m_Data[Size]; 47 | 48 | public: 49 | 50 | typedef std::shared_ptr> Ptr; 51 | 52 | static Ptr Create(std::initializer_list data); 53 | 54 | Uniform(); 55 | 56 | virtual void Bind(unsigned int program, const std::string &name) override; 57 | 58 | virtual bool Load(const void* wrapper, bool object = true) override; 59 | 60 | virtual void Save(void* wrapper, bool object = true) override; 61 | 62 | void SetData(std::initializer_list data); 63 | 64 | Datatype GetDataAt(unsigned int index); 65 | }; 66 | 67 | typedef Uniform Uniform1f; 68 | 69 | typedef Uniform Uniform2f; 70 | 71 | typedef Uniform Uniform3f; 72 | 73 | typedef Uniform Uniform4f; 74 | 75 | typedef Uniform UniformMatrix4fv; 76 | 77 | typedef Uniform Uniform1i; 78 | 79 | typedef Uniform Uniform2i; 80 | 81 | typedef Uniform Uniform3i; 82 | 83 | typedef Uniform Uniform4i; 84 | 85 | typedef Uniform Uniform1ui; 86 | 87 | typedef Uniform Uniform2ui; 88 | 89 | typedef Uniform Uniform3ui; 90 | 91 | typedef Uniform Uniform4ui; 92 | } 93 | 94 | #endif // _FURY_UNIFORM_H_ -------------------------------------------------------------------------------- /engine/Fury/Vector4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "Fury/Vector4.h" 4 | 5 | namespace fury 6 | { 7 | const Vector4 Vector4::YAxis(0.0f, 1.0f, 0.0f, 0.0f); 8 | 9 | const Vector4 Vector4::NegYAxis(0.0f, -1.0f, 0.0f, 0.0f); 10 | 11 | const Vector4 Vector4::XAxis(1.0f, 0.0f, 0.0f, 0.0f); 12 | 13 | const Vector4 Vector4::NegXAxis(-1.0f, 0.0f, 0.0f, 0.0f); 14 | 15 | const Vector4 Vector4::ZAxis(0.0f, 0.0f, 1.0f, 0.0f); 16 | 17 | const Vector4 Vector4::NegZAxis(0.0f, 0.0f, -1.0f, 0.0f); 18 | 19 | void Vector4::Absolute() 20 | { 21 | x = std::abs(x); 22 | y = std::abs(y); 23 | z = std::abs(z); 24 | w = 1.0f; 25 | } 26 | 27 | void Vector4::Zero() 28 | { 29 | x = y = z = 0.0f; 30 | w = 1.0f; 31 | } 32 | 33 | void Vector4::Normalize() 34 | { 35 | float mag = x * x + y * y + z * z; 36 | if(mag > 0.0f) 37 | { 38 | float a = 1.0f / sqrt(mag); 39 | x *= a; y *= a; z *= a; 40 | } 41 | w = 1.0f; 42 | } 43 | 44 | Vector4 Vector4::Normalized() const 45 | { 46 | Vector4 vector(*this); 47 | vector.Normalize(); 48 | return vector; 49 | } 50 | 51 | float Vector4::Length() const 52 | { 53 | return sqrt(x * x + y * y + z * z); 54 | } 55 | 56 | float Vector4::SquareLength() const 57 | { 58 | return x * x + y * y + z * z; 59 | } 60 | 61 | float Vector4::Distance(Vector4 other) const 62 | { 63 | float dx = x - other.x; 64 | float dy = y - other.y; 65 | float dz = z - other.z; 66 | return sqrt(dx * dx + dy * dy + dz * dz); 67 | } 68 | 69 | Vector4 Vector4::CrossProduct(Vector4 other) const 70 | { 71 | return Vector4( 72 | y * other.z - z * other.y, 73 | z * other.x - x * other.z, 74 | x * other.y - y * other.x, 75 | 1.0f 76 | ); 77 | } 78 | 79 | Vector4 Vector4::Project(Vector4 other) const 80 | { 81 | return other * (*this * other / other.SquareLength()); 82 | } 83 | 84 | Vector4 Vector4::Clone() const 85 | { 86 | return Vector4(*this); 87 | } 88 | 89 | bool Vector4::operator == (Vector4 other) const 90 | { 91 | return x == other.x && y == other.y && z == other.z; 92 | } 93 | 94 | bool Vector4::operator != (Vector4 other) const 95 | { 96 | return x != other.x || y != other.y || z != other.z; 97 | } 98 | 99 | bool Vector4::operator < (Vector4 other) const 100 | { 101 | return x < other.x && y < other.y && z < other.z; 102 | } 103 | 104 | bool Vector4::operator <= (Vector4 other) const 105 | { 106 | return x <= other.x && y <= other.y && z <= other.z; 107 | } 108 | 109 | bool Vector4::operator > (Vector4 other) const 110 | { 111 | return x > other.x && y > other.y && z > other.z; 112 | } 113 | 114 | bool Vector4::operator >= (Vector4 other) const 115 | { 116 | return x >= other.x && y >= other.y && z >= other.z; 117 | } 118 | 119 | Vector4 &Vector4::operator = (Vector4 other) 120 | { 121 | x = other.x; y = other.y; z = other.z; 122 | return *this; 123 | } 124 | 125 | Vector4 Vector4::operator - () const 126 | { 127 | return Vector4(-x, -y, -z, 1.0f); 128 | } 129 | 130 | Vector4 Vector4::operator + (Vector4 other) const 131 | { 132 | return Vector4(x + other.x, y + other.y, z + other.z, 1.0f); 133 | } 134 | 135 | Vector4 Vector4::operator - (Vector4 other) const 136 | { 137 | return Vector4(x - other.x, y - other.y, z - other.z, 1.0f); 138 | } 139 | 140 | float Vector4::operator * (Vector4 other) const 141 | { 142 | return x * other.x + y * other.y + z * other.z; 143 | } 144 | 145 | Vector4 Vector4::operator * (const float other) const 146 | { 147 | return Vector4(x * other, y * other, z * other, 1.0f); 148 | } 149 | 150 | Vector4 Vector4::operator / (const float other) const 151 | { 152 | float i = 1.0f / other; 153 | return Vector4(x * i, y * i, z * i, 1.0f); 154 | } 155 | 156 | std::ostream &operator << (std::ostream &os, const Vector4 &data) 157 | { 158 | return os << "Vector4(" << data.x << ", " << data.y << ", " << data.z << ", " << data.w << ")"; 159 | } 160 | } -------------------------------------------------------------------------------- /engine/Fury/Vector4.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_VECTOR4_H_ 2 | #define _FURY_VECTOR4_H_ 3 | 4 | #include 5 | 6 | #include "Macros.h" 7 | 8 | namespace fury 9 | { 10 | /** 11 | * When you need a Vector4 with special w. 12 | * Call Vector4(yourVector, yourW) to create one to make sure it's w is correct. 13 | */ 14 | class FURY_API Vector4 15 | { 16 | public: 17 | 18 | // 0,1,0,0 19 | static const Vector4 YAxis; 20 | 21 | // 0,-1,0,0 22 | static const Vector4 NegYAxis; 23 | 24 | // 1,0,0,0 25 | static const Vector4 XAxis; 26 | 27 | // -1,0,0,0 28 | static const Vector4 NegXAxis; 29 | 30 | // 0,0,1,0 31 | static const Vector4 ZAxis; 32 | 33 | // 0,0,-1,0 34 | static const Vector4 NegZAxis; 35 | 36 | float x, y, z, w; 37 | 38 | Vector4() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) {} 39 | 40 | Vector4(const Vector4 &other) : x(other.x), y(other.y), z(other.z), w(other.w) {} 41 | 42 | Vector4(Vector4 other, const float w) : x(other.x), y(other.y), z(other.z), w(w) {} 43 | 44 | Vector4(float value) : x(value), y(value), z(value), w(1) {} 45 | 46 | Vector4(float value, float w) : x(value), y(value), z(value), w(w) {} 47 | 48 | Vector4(float x, float y, float z) : x(x), y(y), z(z), w(1) {} 49 | 50 | Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} 51 | 52 | void Absolute(); 53 | 54 | void Zero(); 55 | 56 | void Normalize(); 57 | 58 | Vector4 Normalized() const; 59 | 60 | float Length() const; 61 | 62 | float SquareLength() const; 63 | 64 | float Distance(Vector4 other) const; 65 | 66 | Vector4 CrossProduct(Vector4 other) const; 67 | 68 | Vector4 Project(Vector4 other) const; 69 | 70 | Vector4 Clone() const; 71 | 72 | // all operator ignores w component. 73 | // or will simply set w to 1.0 74 | 75 | bool operator == (Vector4 other) const; 76 | 77 | bool operator != (Vector4 other) const; 78 | 79 | bool operator < (Vector4 other) const; 80 | 81 | bool operator <= (Vector4 other) const; 82 | 83 | bool operator > (Vector4 other) const; 84 | 85 | bool operator >= (Vector4 other) const; 86 | 87 | Vector4 &operator = (Vector4 other); 88 | 89 | Vector4 operator - () const; 90 | 91 | Vector4 operator + (Vector4 other) const; 92 | 93 | Vector4 operator - (Vector4 other) const; 94 | 95 | float operator * (Vector4 other) const; 96 | 97 | Vector4 operator * (const float other) const; 98 | 99 | Vector4 operator / (const float other) const; 100 | 101 | }; 102 | 103 | std::ostream FURY_API &operator << (std::ostream &os, const Vector4 &data); 104 | } 105 | 106 | #endif // _FURY_VECTOR4_H_ -------------------------------------------------------------------------------- /engine/ThirdParty/ImGui/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // USER IMPLEMENTATION 3 | // This file contains compile-time options for ImGui. 4 | // Other options (memory allocation overrides, callbacks, etc.) can be set at runtime via the ImGuiIO structure - ImGui::GetIO(). 5 | //----------------------------------------------------------------------------- 6 | 7 | #pragma once 8 | 9 | #include "Fury/Macros.h" 10 | 11 | #define IM_ASSERT(_EXPR) ASSERT_MSG(_EXPR, "ImGui Assert!") 12 | 13 | #if defined(_WIN32) 14 | 15 | #ifdef FURY_API_EXPORT 16 | #define IMGUI_API __declspec(dllexport) 17 | #else 18 | #define IMGUI_API __declspec(dllimport) 19 | #endif 20 | 21 | #else 22 | 23 | #define IMGUI_API 24 | 25 | #endif 26 | 27 | #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 28 | 29 | //---- Define assertion handler. Defaults to calling assert(). 30 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 31 | 32 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows. 33 | //#define IMGUI_API __declspec( dllexport ) 34 | //#define IMGUI_API __declspec( dllimport ) 35 | 36 | //---- Include imgui_user.h at the end of imgui.h 37 | //#define IMGUI_INCLUDE_IMGUI_USER_H 38 | 39 | //---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) 40 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS 41 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS 42 | 43 | //---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) 44 | //#define IMGUI_DISABLE_TEST_WINDOWS 45 | 46 | //---- Don't define obsolete functions names 47 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 48 | 49 | //---- Implement STB libraries in a namespace to avoid conflicts 50 | //#define IMGUI_STB_NAMESPACE ImGuiStb 51 | 52 | //---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. 53 | /* 54 | #define IM_VEC2_CLASS_EXTRA \ 55 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 56 | operator MyVec2() const { return MyVec2(x,y); } 57 | 58 | #define IM_VEC4_CLASS_EXTRA \ 59 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 60 | operator MyVec4() const { return MyVec4(x,y,z,w); } 61 | */ 62 | 63 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 64 | //---- e.g. create variants of the ImGui::Value() helper for your low-level math types, or your own widgets/helpers. 65 | /* 66 | namespace ImGui 67 | { 68 | void Value(const char* prefix, const MyMatrix44& v, const char* float_format = NULL); 69 | } 70 | */ 71 | 72 | -------------------------------------------------------------------------------- /engine/ThirdParty/ImGui/imgui_fury.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // offsetof 3 | #include 4 | #include 5 | 6 | #include "ImGui/imgui.h" 7 | #include "ImGui/imgui_fury.h" 8 | 9 | namespace ImGui 10 | { 11 | struct PlotVarData 12 | { 13 | ImGuiID ID; 14 | ImVector Data; 15 | int DataInsertIdx; 16 | int LastFrame; 17 | 18 | PlotVarData() : ID(0), DataInsertIdx(0), LastFrame(-1) {} 19 | }; 20 | 21 | typedef std::map PlotVarsMap; 22 | static PlotVarsMap g_PlotVarsMap; 23 | 24 | // Plot value over time 25 | // Call with 'value == FLT_MAX' to draw without adding new value to the buffer 26 | void PlotVar(const char* label, float value, float scale_min, float scale_max, float width, float height, size_t buffer_size) 27 | { 28 | IM_ASSERT(label); 29 | if (buffer_size == 0) 30 | buffer_size = 120; 31 | 32 | ImGui::PushID(label); 33 | ImGuiID id = ImGui::GetID(""); 34 | 35 | // Lookup O(log N) 36 | PlotVarData& pvd = g_PlotVarsMap[id]; 37 | 38 | // Setup 39 | if (pvd.Data.capacity() != buffer_size) 40 | { 41 | pvd.Data.resize(buffer_size); 42 | memset(&pvd.Data[0], 0, sizeof(float) * buffer_size); 43 | pvd.DataInsertIdx = 0; 44 | pvd.LastFrame = -1; 45 | } 46 | 47 | // Insert (avoid unnecessary modulo operator) 48 | if (pvd.DataInsertIdx == buffer_size) 49 | pvd.DataInsertIdx = 0; 50 | int display_idx = pvd.DataInsertIdx; 51 | if (value != FLT_MAX) 52 | pvd.Data[pvd.DataInsertIdx++] = value; 53 | 54 | // Draw 55 | int current_frame = ImGui::GetFrameCount(); 56 | if (pvd.LastFrame != current_frame) 57 | { 58 | std::string hint = std::string(label) + " " + std::to_string((int)value); 59 | ImGui::PlotLines("##plot", &pvd.Data[0], buffer_size, pvd.DataInsertIdx, hint.c_str(), scale_min, scale_max, ImVec2(width, height)); 60 | pvd.LastFrame = current_frame; 61 | } 62 | 63 | ImGui::PopID(); 64 | } 65 | 66 | void PlotVarFlushOldEntries() 67 | { 68 | int current_frame = ImGui::GetFrameCount(); 69 | for (PlotVarsMap::iterator it = g_PlotVarsMap.begin(); it != g_PlotVarsMap.end(); ) 70 | { 71 | PlotVarData& pvd = it->second; 72 | if (pvd.LastFrame < current_frame - std::max(400,(int)pvd.Data.size())) 73 | it = g_PlotVarsMap.erase(it); 74 | else 75 | ++it; 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /engine/ThirdParty/ImGui/imgui_fury.h: -------------------------------------------------------------------------------- 1 | #ifndef _FURY_IMGUI_H_ 2 | #define _FURY_IMGUI_H_ 3 | 4 | #include 5 | #include "ImGui/imconfig.h" 6 | 7 | namespace ImGui 8 | { 9 | // Plot value over time 10 | // Pass FLT_MAX value to draw without adding a new value 11 | void IMGUI_API PlotVar(const char* label, float value, float scale_min = FLT_MAX, float scale_max = FLT_MAX, float width = 200, float height = 40, size_t buffer_size = 120); 12 | 13 | // Call this periodically to discard old/unused data 14 | void IMGUI_API PlotVarFlushOldEntries(); 15 | } 16 | 17 | #endif // _FURY_IMGUI_H_ -------------------------------------------------------------------------------- /engine/ThirdParty/LZ4/LICENSE: -------------------------------------------------------------------------------- 1 | LZ4 Library 2 | Copyright (c) 2011-2014, Yann Collet 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or 13 | other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | 3 | project(FuryDemo) 4 | 5 | if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") 6 | set(OS_WINDOWS 1) 7 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 8 | set(OS_MACOSX 1) 9 | endif() 10 | 11 | set(CMAKE_CXX_FLAGS "-std=c++11") 12 | 13 | set(FURY3D_INCLUDE "" CACHE PATH "Location of fury3d headers.") 14 | set(FURY3D_LIB "" CACHE PATH "Location of fury3d lib.") 15 | 16 | set(SFML_INCLUDE "/usr/local/include" CACHE PATH "Location of SFML headers.") 17 | set(SFML_LIB "/usr/local/lib" CACHE PATH "Location of SFML lib.") 18 | 19 | option(FBXPARSER_IMP "Fury Use FbxParser." OFF) 20 | if(FBXPARSER_IMP) 21 | add_definitions(-D_FURY_FBXPARSER_IMP_) 22 | set(FBXSDK_INCLUDE "" CACHE PATH "Location of fbxsdk headers.") 23 | set(FBXSDK_LIB_RELEASE "/usr/local/lib" CACHE FILEPATH "Path to fbxsdk release lib.") 24 | set(FBXSDK_LIB_DEBUG "/usr/local/lib" CACHE FILEPATH "Path to fbxsdk debug lib.") 25 | set(FBXSDK_LIB optimized ${FBXSDK_LIB_RELEASE} debug ${FBXSDK_LIB_DEBUG}) 26 | endif() 27 | 28 | option(GUI_IMP "Fury Use ImGui." ON) 29 | if(GUI_IMP) 30 | add_definitions(-D_FURY_GUI_IMP_) 31 | endif() 32 | 33 | include_directories(${PROJECT_SOURCE_DIR}/include) 34 | 35 | if(FBXPARSER_IMP) 36 | include_directories(${FBXSDK_INCLUDE}) 37 | endif() 38 | 39 | include_directories(${FURY3D_INCLUDE}) 40 | include_directories(${FURY3D_INCLUDE}/ThirdParty) 41 | link_directories(${FURY3D_LIB}) 42 | 43 | include_directories(${SFML_INCLUDE}) 44 | link_directories(${SFML_LIB}) 45 | 46 | if(OS_MACOSX) 47 | find_package(OpenGL REQUIRED) 48 | include_directories(${OPENGL_INCLUDE_DIR}) 49 | endif() 50 | 51 | file(GLOB DEMO_SRC ${DEMO_SRC} "*.cpp") 52 | add_executable(demo ${DEMO_SRC}) 53 | if(OS_WINDOWS) 54 | target_link_libraries(demo libfury sfml-graphics sfml-window sfml-system opengl32 ${FBXSDK_LIB}) 55 | elseif(OS_MACOSX) 56 | target_link_libraries(demo fury sfml-graphics sfml-window sfml-system ${OPENGL_LIBRARIES} ${FBXSDK_LIB}) 57 | set_target_properties(demo PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@executable_path") 58 | endif() 59 | 60 | if(OS_WINDOWS) 61 | install(TARGETS demo DESTINATION bin) 62 | elseif(OS_MACOSX) 63 | install(TARGETS demo DESTINATION bin/demo.app/Contents/MacOS) 64 | endif() -------------------------------------------------------------------------------- /examples/Demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | using namespace fury; 8 | 9 | #undef near 10 | #undef far 11 | #undef max 12 | 13 | #define TICKS_PER_SECOND 25 14 | #define SKIP_TICKS 1000 / TICKS_PER_SECOND 15 | #define MAX_FRAMESKIP 5 16 | 17 | OcTree::Ptr m_OcTree; 18 | 19 | SceneNode::Ptr m_CamNode; 20 | 21 | void Pause(); 22 | 23 | void Initialize(); 24 | 25 | void Update(float dt); 26 | 27 | void FixedUpdate(); 28 | 29 | void Shutdown(); 30 | 31 | int main(int argc, char *argv[]) 32 | { 33 | // setup sfml 34 | sf::Window window( 35 | sf::VideoMode(1920, 1080), 36 | "Fury3d", 37 | sf::Style::Titlebar | sf::Style::Close /*| sf::Style::Fullscreen*/, 38 | sf::ContextSettings(24, 8, 0, 3, 3) 39 | ); 40 | window.setKeyRepeatEnabled(true); 41 | window.setVerticalSyncEnabled(false); 42 | window.setActive(); 43 | //window.setFramerateLimit(60); 44 | 45 | //if (argc < 2) Pause(); 46 | 47 | if (!Engine::Initialize(window, 2, 2, LogLevel::DBUG, FileUtil::GetAbsPath("Log.txt").c_str())) 48 | return false; 49 | 50 | Initialize(); 51 | 52 | // Game Loop 53 | sf::Clock clock; 54 | sf::Event event; 55 | sf::Int32 next_game_tick = clock.getElapsedTime().asMilliseconds(); 56 | bool running = true; 57 | 58 | while (window.isOpen() && running) 59 | { 60 | RenderUtil::Instance()->BeginFrame(); 61 | 62 | // Sync event 63 | while (window.pollEvent(event)) 64 | { 65 | if (event.type == sf::Event::Closed) 66 | { 67 | running = false; 68 | break; 69 | } 70 | Engine::HandleEvent(event); 71 | } 72 | 73 | // Update game logic TICKS_PER_SECOND times per second. 74 | int numLoops = 0; 75 | while (clock.getElapsedTime().asMilliseconds() > next_game_tick && numLoops < MAX_FRAMESKIP && running) 76 | { 77 | FixedUpdate(); 78 | next_game_tick += SKIP_TICKS; 79 | numLoops++; 80 | } 81 | // display game object in maximum framerate. 82 | sf::Int32 elapsed = clock.getElapsedTime().asMilliseconds(); 83 | float dt = float(elapsed + SKIP_TICKS - next_game_tick) / float(SKIP_TICKS); 84 | next_game_tick -= elapsed; 85 | 86 | Gui::NewFrame(clock.restart().asSeconds()); 87 | Update(dt); 88 | 89 | window.display(); 90 | 91 | RenderUtil::Instance()->EndFrame(); 92 | } 93 | 94 | Shutdown(); 95 | return EXIT_SUCCESS; 96 | } 97 | 98 | void Pause() 99 | { 100 | std::cout << "Press ENTER to continue..."; 101 | std::cin.ignore(std::numeric_limits::max(), '\n'); 102 | } 103 | 104 | void Initialize() 105 | { 106 | m_OcTree = OcTree::Create(Vector4(-1000, -1000, -1000, 1), Vector4(1000, 1000, 1000, 1), 2); 107 | Scene::Active = Scene::Create("main", FileUtil::GetAbsPath(), m_OcTree); 108 | FileUtil::LoadCompressedFile(Scene::Active, FileUtil::GetAbsPath("Resource/Scene/scene.bin")); 109 | 110 | auto camera = Camera::Create(); 111 | camera->PerspectiveFov(0.7854f, 1.778f, 1, 100); 112 | camera->SetShadowFar(30); 113 | camera->SetShadowBounds(Vector4(-5), Vector4(5)); 114 | 115 | m_CamNode = SceneNode::Create("camNode"); 116 | m_CamNode->SetLocalPosition(Vector4(0.0f, 10.0f, 25.0f, 1.0f)); 117 | m_CamNode->SetLocalRoattion(MathUtil::EulerRadToQuat(0.0f, -MathUtil::DegToRad * 30.0f, 0.0f)); 118 | m_CamNode->Recompose(); 119 | m_CamNode->AddComponent(Transform::Create()); 120 | m_CamNode->AddComponent(camera); 121 | m_CamNode->Recompose(true); 122 | 123 | // setup pipeline 124 | Pipeline::Active = PrelightPipeline::Create("pipeline"); 125 | Pipeline::Active->SetCurrentCamera(m_CamNode); 126 | FileUtil::LoadFile(Pipeline::Active, FileUtil::GetAbsPath("Resource/Pipeline/DefferedLightingLambert.json")); 127 | } 128 | 129 | void Update(float dt) 130 | { 131 | Engine::Update(dt); 132 | Gui::ShowDefault(dt); 133 | Gui::Render(); 134 | Pipeline::Active->Execute(m_OcTree); 135 | } 136 | 137 | void FixedUpdate() 138 | { 139 | Engine::FixedUpdate(); 140 | } 141 | 142 | void Shutdown() 143 | { 144 | m_OcTree = nullptr; 145 | m_CamNode = nullptr; 146 | Engine::Shutdown(); 147 | } -------------------------------------------------------------------------------- /examples/bin/Resource/Pipeline/DefferedLightingLambert.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deffered_lighting_pipeline", 3 | "shaders": [ 4 | { 5 | "name": "gbuffer_shader", 6 | "path": "Resource/Shader/Lambert/Gbuffer.glsl", 7 | "type": "static_mesh", 8 | "textures" : ["diffuse"], 9 | "defines": ["STATIC_MESH"] 10 | }, 11 | { 12 | "name": "gbuffer_notexture_shader", 13 | "path": "Resource/Shader/Lambert/GBufferNoTexture.glsl", 14 | "type": "static_mesh", 15 | "textures" : ["color_only"], 16 | "defines": ["STATIC_MESH"] 17 | }, 18 | { 19 | "name": "gbuffer_skin_shader", 20 | "path": "Resource/Shader/Lambert/Gbuffer.glsl", 21 | "type": "skinned_mesh", 22 | "textures" : ["diffuse"], 23 | "defines": ["SKINNED_MESH"] 24 | }, 25 | { 26 | "name": "gbuffer_notexture_skin_shader", 27 | "path": "Resource/Shader/Lambert/GBufferNoTexture.glsl", 28 | "type": "skinned_mesh", 29 | "textures" : ["color_only"], 30 | "defines": ["SKINNED_MESH"] 31 | }, 32 | { 33 | "name": "pointlight_shader", 34 | "path": "Resource/Shader/Lambert/PointLight.glsl" 35 | }, 36 | { 37 | "name": "dirlight_shader", 38 | "path": "Resource/Shader/Lambert/SunLight.glsl" 39 | }, 40 | { 41 | "name": "spotlight_shader", 42 | "path": "Resource/Shader/Lambert/SpotLight.glsl" 43 | }, 44 | { 45 | "name": "pointlight_shadow_shader", 46 | "path": "Resource/Shader/Lambert/PointLight.glsl", 47 | "defines": ["SHADOW"] 48 | }, 49 | { 50 | "name": "dirlight_shadow_shader", 51 | "path": "Resource/Shader/Lambert/SunLight.glsl", 52 | "defines": ["SHADOW"] 53 | }, 54 | { 55 | "name": "spotlight_shadow_shader", 56 | "path": "Resource/Shader/Lambert/SpotLight.glsl", 57 | "defines": ["SHADOW"] 58 | }, 59 | { 60 | "name": "dirlight_csm_shader", 61 | "path": "Resource/Shader/Lambert/SunLight.glsl", 62 | "defines": ["CSM"] 63 | }, 64 | { 65 | "name": "lambert_shader", 66 | "path": "Resource/Shader/Lambert/Lambert.glsl" 67 | }, 68 | { 69 | "name": "depth_shader", 70 | "path": "Resource/Shader/DrawDepth.glsl" 71 | }, 72 | { 73 | "name": "leagcy_depth_shader", 74 | "path": "Resource/Shader/DrawDepthLeagcy.glsl" 75 | }, 76 | { 77 | "name": "cube_depth_shader", 78 | "path": "Resource/Shader/DrawDepthCube.glsl" 79 | } 80 | ], 81 | "textures": [ 82 | { 83 | "name": "gbuffer_depth", 84 | "format": "depth24", 85 | "width": 1280, 86 | "height": 720 87 | }, 88 | { 89 | "name": "gbuffer_normal", 90 | "format": "rgba16", 91 | "width": 1280, 92 | "height": 720 93 | }, 94 | { 95 | "name": "gbuffer_diffuse", 96 | "format": "rgba8", 97 | "width": 1280, 98 | "height": 720 99 | }, 100 | { 101 | "name": "gbuffer_light", 102 | "format": "rgba8", 103 | "width": 1280, 104 | "height": 720 105 | } 106 | ], 107 | "passes": [ 108 | { 109 | "name": "pass_gbuffer", 110 | "camera": "camNode", 111 | "shaders": [ 112 | "gbuffer_shader", 113 | "gbuffer_notexture_shader", 114 | "gbuffer_skin_shader", 115 | "gbuffer_notexture_skin_shader" 116 | ], 117 | "index": 0, 118 | "input": [], 119 | "output": [ 120 | "gbuffer_depth", 121 | "gbuffer_normal", 122 | "gbuffer_diffuse" 123 | ], 124 | "blendMode": "replace", 125 | "drawMode": "opaque" 126 | }, 127 | { 128 | "name": "pass_light", 129 | "camera": "camNode", 130 | "index": 1, 131 | "input": [ 132 | "gbuffer_depth", 133 | "gbuffer_normal" 134 | ], 135 | "output": [ 136 | "gbuffer_light" 137 | ], 138 | "blendMode": "add", 139 | "clearMode": "color", 140 | "clearColor": [0.01, 0.01, 0.01, 1.0], 141 | "drawMode": "light" 142 | }, 143 | { 144 | "name": "pass_final", 145 | "camera": "camNode", 146 | "shaders": [ 147 | "lambert_shader" 148 | ], 149 | "index": 2, 150 | "input": [ 151 | "gbuffer_light", 152 | "gbuffer_diffuse" 153 | ], 154 | "output": [], 155 | "blendMode": "replace", 156 | "drawMode": "quad" 157 | } 158 | ] 159 | } -------------------------------------------------------------------------------- /examples/bin/Resource/Scene/body.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/Resource/Scene/body.jpg -------------------------------------------------------------------------------- /examples/bin/Resource/Scene/grass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/Resource/Scene/grass.jpg -------------------------------------------------------------------------------- /examples/bin/Resource/Scene/james.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/Resource/Scene/james.fbx -------------------------------------------------------------------------------- /examples/bin/Resource/Scene/outdoor.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/Resource/Scene/outdoor.fbx -------------------------------------------------------------------------------- /examples/bin/Resource/Scene/scene.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/Resource/Scene/scene.bin -------------------------------------------------------------------------------- /examples/bin/Resource/Scene/tank.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/Resource/Scene/tank.fbx -------------------------------------------------------------------------------- /examples/bin/Resource/Scene/unspecified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/Resource/Scene/unspecified.png -------------------------------------------------------------------------------- /examples/bin/Resource/Scene/wheels.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/Resource/Scene/wheels.jpg -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/DrawDepth.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | 7 | out float out_depth; 8 | 9 | uniform mat4 projection_matrix; 10 | uniform mat4 invert_view_matrix; 11 | uniform mat4 world_matrix; 12 | 13 | void main() 14 | { 15 | vec4 viewPos = invert_view_matrix * world_matrix * vec4(vertex_position, 1.0); 16 | out_depth = -viewPos.z; 17 | 18 | gl_Position = projection_matrix * viewPos; 19 | } 20 | 21 | #endif 22 | 23 | #ifdef FRAGMENT_SHADER 24 | 25 | uniform float camera_far = 10000; 26 | 27 | in float out_depth; 28 | 29 | void main() 30 | { 31 | gl_FragDepth = out_depth / camera_far; 32 | } 33 | 34 | #endif -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/DrawDepthCube.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | 7 | out vec4 world_position; 8 | 9 | uniform mat4 projection_matrix; 10 | uniform mat4 invert_view_matrix; 11 | uniform mat4 world_matrix; 12 | 13 | void main() 14 | { 15 | world_position = world_matrix * vec4(vertex_position, 1.0); 16 | gl_Position = projection_matrix * invert_view_matrix * world_position; 17 | } 18 | 19 | #endif 20 | 21 | #ifdef FRAGMENT_SHADER 22 | 23 | uniform float light_far = 10000; 24 | uniform vec3 light_pos; 25 | 26 | in vec4 world_position; 27 | 28 | void main() 29 | { 30 | gl_FragDepth = length(world_position.xyz - light_pos) / light_far; 31 | } 32 | 33 | #endif -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/DrawDepthLeagcy.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | 7 | uniform mat4 projection_matrix; 8 | uniform mat4 invert_view_matrix; 9 | uniform mat4 world_matrix; 10 | 11 | void main() 12 | { 13 | gl_Position = projection_matrix * invert_view_matrix * world_matrix * vec4(vertex_position, 1.0); 14 | } 15 | 16 | #endif 17 | 18 | #ifdef FRAGMENT_SHADER 19 | 20 | void main() 21 | { 22 | // gl_FragDepth = gl_FragCoord.z; 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/Lambert/GBuffer.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | in vec2 vertex_uv; 7 | in vec3 vertex_normal; 8 | 9 | #ifdef SKINNED_MESH 10 | in ivec4 bone_ids; 11 | in vec3 bone_weights; 12 | uniform mat4 bone_matrices[35]; 13 | #endif 14 | 15 | out vec3 out_normal; 16 | out vec2 out_uv; 17 | out float out_depth; 18 | 19 | uniform mat4 projection_matrix; 20 | uniform mat4 invert_view_matrix; 21 | uniform mat4 world_matrix; 22 | 23 | void main() 24 | { 25 | #ifdef SKINNED_MESH 26 | mat4 bone_matrix = bone_matrices[bone_ids[0]] * bone_weights[0]; 27 | bone_matrix += bone_matrices[bone_ids[1]] * bone_weights[1]; 28 | bone_matrix += bone_matrices[bone_ids[2]] * bone_weights[2]; 29 | bone_matrix += bone_matrices[bone_ids[3]] * (1.0f - bone_weights[0] - bone_weights[1] - bone_weights[2]); 30 | vec4 worldPos = world_matrix * bone_matrix * vec4(vertex_position, 1.0); 31 | out_normal = normalize(invert_view_matrix * world_matrix * bone_matrix * vec4(vertex_normal, 0.0)).xyz; 32 | #else 33 | vec4 worldPos = world_matrix * vec4(vertex_position, 1.0); 34 | out_normal = normalize(invert_view_matrix * world_matrix * vec4(vertex_normal, 0.0)).xyz; 35 | #endif 36 | 37 | vec4 viewPos = invert_view_matrix * worldPos; 38 | out_depth = -viewPos.z; 39 | out_uv = vertex_uv; 40 | 41 | gl_Position = projection_matrix * viewPos; 42 | } 43 | 44 | #endif 45 | 46 | #ifdef FRAGMENT_SHADER 47 | 48 | in vec3 out_normal; 49 | in vec2 out_uv; 50 | in float out_depth; 51 | 52 | uniform float camera_far = 10000; 53 | 54 | uniform vec3 ambient_color; 55 | 56 | uniform sampler2D diffuse_texture; 57 | 58 | uniform float ambient_factor = 1; 59 | uniform float diffuse_factor = 1; 60 | 61 | // normal.xyz, shininess 62 | layout (location = 0) out vec4 rt0; 63 | // diffuse rgb, specular intensity 64 | layout (location = 1) out vec4 rt1; 65 | 66 | void main() 67 | { 68 | rt0.rgb = (out_normal.rgb + 1) * 0.5; 69 | rt0.a = 1.0; 70 | 71 | rt1.rgb = texture(diffuse_texture, out_uv).rgb * diffuse_factor + ambient_color * ambient_factor; 72 | rt1.a = 1.0; 73 | 74 | gl_FragDepth = out_depth / camera_far; 75 | } 76 | 77 | #endif -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/Lambert/GBufferNoTexture.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | in vec3 vertex_normal; 7 | 8 | #ifdef SKINNED_MESH 9 | in ivec4 bone_ids; 10 | in vec3 bone_weights; 11 | uniform mat4 bone_matrices[35]; 12 | #endif 13 | 14 | out vec3 out_normal; 15 | out float out_depth; 16 | 17 | uniform mat4 projection_matrix; 18 | uniform mat4 invert_view_matrix; 19 | uniform mat4 world_matrix; 20 | 21 | void main() 22 | { 23 | #ifdef SKINNED_MESH 24 | mat4 bone_matrix = bone_matrices[bone_ids[0]] * bone_weights[0]; 25 | bone_matrix += bone_matrices[bone_ids[1]] * bone_weights[1]; 26 | bone_matrix += bone_matrices[bone_ids[2]] * bone_weights[2]; 27 | bone_matrix += bone_matrices[bone_ids[3]] * (1.0f - bone_weights[0] - bone_weights[1] - bone_weights[2]); 28 | vec4 worldPos = world_matrix * bone_matrix * vec4(vertex_position, 1.0); 29 | out_normal = normalize(invert_view_matrix * world_matrix * bone_matrix * vec4(vertex_normal, 0.0)).xyz; 30 | #else 31 | vec4 worldPos = world_matrix * vec4(vertex_position, 1.0); 32 | out_normal = normalize(invert_view_matrix * world_matrix * vec4(vertex_normal, 0.0)).xyz; 33 | #endif 34 | 35 | vec4 viewPos = invert_view_matrix * worldPos; 36 | out_depth = -viewPos.z; 37 | 38 | gl_Position = projection_matrix * viewPos; 39 | } 40 | 41 | #endif 42 | 43 | #ifdef FRAGMENT_SHADER 44 | 45 | in vec3 out_normal; 46 | in float out_depth; 47 | 48 | uniform float camera_far = 10000; 49 | 50 | uniform vec3 ambient_color; 51 | uniform vec3 diffuse_color; 52 | 53 | uniform float ambient_factor = 1; 54 | uniform float diffuse_factor = 1; 55 | 56 | // normal.xyz, shininess 57 | layout (location = 0) out vec4 rt0; 58 | // diffuse rgb 59 | layout (location = 1) out vec4 rt1; 60 | 61 | void main() 62 | { 63 | rt0.rgb = (out_normal.rgb + 1) * 0.5; 64 | rt0.a = 1.0; 65 | 66 | rt1.rgb = diffuse_color.rgb * diffuse_factor + ambient_color * ambient_factor; 67 | rt1.a = 1.0; 68 | 69 | gl_FragDepth = out_depth / camera_far; 70 | } 71 | 72 | #endif -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/Lambert/Lambert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | in vec2 vertex_uv; 7 | 8 | out vec2 out_uv; 9 | 10 | void main() 11 | { 12 | out_uv = vertex_uv; 13 | gl_Position = vec4(vertex_position.xy, 0.0, 1.0); 14 | } 15 | 16 | #endif 17 | 18 | #ifdef FRAGMENT_SHADER 19 | 20 | in vec2 out_uv; 21 | 22 | out vec4 fragment_output; 23 | 24 | uniform sampler2D gbuffer_diffuse; 25 | uniform sampler2D gbuffer_light; 26 | 27 | void main() 28 | { 29 | vec4 diffuse = texture(gbuffer_diffuse, out_uv); 30 | vec4 lighting = texture(gbuffer_light, out_uv); 31 | 32 | fragment_output.rgb = lighting.rgb * diffuse.rgb; 33 | fragment_output.a = 1.0; 34 | } 35 | 36 | #endif -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/Lambert/PointLight.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | 7 | out vec3 vs_pos; 8 | out vec4 ss_pos; 9 | 10 | uniform mat4 projection_matrix; 11 | uniform mat4 invert_view_matrix; 12 | uniform mat4 world_matrix; 13 | 14 | void main() 15 | { 16 | vs_pos = (invert_view_matrix * world_matrix * vec4(vertex_position, 1.0)).xyz; 17 | ss_pos = projection_matrix * vec4(vs_pos, 1); 18 | gl_Position = ss_pos; 19 | } 20 | 21 | #endif 22 | 23 | #ifdef FRAGMENT_SHADER 24 | 25 | out vec4 fragment_output; 26 | 27 | in vec3 vs_pos; 28 | in vec4 ss_pos; 29 | 30 | uniform float camera_far = 10000; 31 | 32 | uniform mat4 invert_view_matrix; 33 | 34 | uniform vec3 light_pos; 35 | uniform vec3 light_color; 36 | uniform float light_falloff; 37 | uniform float light_radius; 38 | uniform float light_intensity; 39 | 40 | // linear depth 41 | uniform sampler2D gbuffer_depth; 42 | // normal, shniness 43 | uniform sampler2D gbuffer_normal; 44 | 45 | #ifdef SHADOW 46 | uniform mat4 shadow_proj; 47 | uniform mat4 shadow_matrix; 48 | uniform samplerCube shadow_buffer; 49 | #endif 50 | 51 | vec3 pos_from_depth(const in vec2 screenUV) 52 | { 53 | float depth = texture(gbuffer_depth, screenUV).r; 54 | vec3 view_ray = vec3(vs_pos.xy * (camera_far / vs_pos.z), camera_far); 55 | return -view_ray * depth; 56 | } 57 | 58 | vec4 apply_lighting(const in vec3 normal, const in vec3 surface_pos) 59 | { 60 | vec3 vs_light_pos = (invert_view_matrix * vec4(light_pos, 1)).xyz; 61 | 62 | vec3 L = vs_light_pos - surface_pos; 63 | 64 | float dist = length(L); 65 | float attenuation = pow(max(0.0, 1.0 - dist / light_radius), light_falloff + 1.0); 66 | 67 | L = normalize(L); 68 | vec3 N = normalize(normal); 69 | 70 | float NdotL = max(0.0, dot(N, L)); 71 | 72 | return vec4( 73 | vec3(1) * light_color * NdotL * attenuation * light_intensity, 1.0 74 | ); 75 | } 76 | 77 | void main() 78 | { 79 | vec2 screenUV = (ss_pos.xy / ss_pos.w) * 0.5 + 0.5; 80 | vec3 vs_surface_pos = pos_from_depth(screenUV); 81 | 82 | vec4 raw_normal = texture(gbuffer_normal, screenUV); 83 | vec3 vs_normal = raw_normal.xyz * 2.0 - 1.0; 84 | 85 | fragment_output = apply_lighting(vs_normal, vs_surface_pos); 86 | 87 | #ifdef SHADOW 88 | // world space pos 89 | vec4 pos = shadow_matrix * vec4(vs_surface_pos, 1.0); 90 | vec3 dir = pos.xyz - light_pos; 91 | 92 | float closest = texture(shadow_buffer, dir).x * light_radius; 93 | float current = length(dir); 94 | 95 | fragment_output *= float(current - 0.002 < closest); 96 | #endif 97 | } 98 | 99 | #endif -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/Lambert/SpotLight.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | 7 | out vec3 vs_dir; 8 | out vec3 vs_pos; 9 | out vec4 ss_pos; 10 | 11 | uniform vec3 light_dir; 12 | 13 | uniform mat4 projection_matrix; 14 | uniform mat4 invert_view_matrix; 15 | uniform mat4 world_matrix; 16 | 17 | void main() 18 | { 19 | vs_dir = normalize(invert_view_matrix * vec4(-light_dir, 0)).xyz; 20 | vs_pos = (invert_view_matrix * world_matrix * vec4(vertex_position, 1.0)).xyz; 21 | ss_pos = projection_matrix * vec4(vs_pos, 1); 22 | gl_Position = ss_pos; 23 | } 24 | 25 | #endif 26 | 27 | #ifdef FRAGMENT_SHADER 28 | 29 | out vec4 fragment_output; 30 | 31 | in vec3 vs_dir; 32 | in vec3 vs_pos; 33 | in vec4 ss_pos; 34 | 35 | uniform float camera_far = 10000; 36 | 37 | uniform mat4 invert_view_matrix; 38 | 39 | uniform vec3 light_pos; 40 | uniform vec3 light_color; 41 | uniform float light_falloff; 42 | uniform float light_radius; 43 | uniform float light_intensity; 44 | uniform float light_innerangle; 45 | uniform float light_outterangle; 46 | 47 | // linear depth 48 | uniform sampler2D gbuffer_depth; 49 | // normal, shniness 50 | uniform sampler2D gbuffer_normal; 51 | 52 | #ifdef SHADOW 53 | uniform mat4 shadow_matrix; 54 | uniform sampler2D shadow_buffer; 55 | #endif 56 | 57 | vec3 pos_from_depth(const in vec2 screenUV) 58 | { 59 | float depth = texture(gbuffer_depth, screenUV).r; 60 | vec3 view_ray = vec3(vs_pos.xy * (camera_far / vs_pos.z), camera_far); 61 | return -view_ray * depth; 62 | } 63 | 64 | vec4 apply_lighting(const in vec3 normal, const in vec3 surface_pos) 65 | { 66 | float halfInner = light_innerangle * 0.5f; 67 | float halfOutter = light_outterangle * 0.5f; 68 | 69 | vec3 vs_light_pos = (invert_view_matrix * vec4(light_pos, 1)).xyz; 70 | 71 | vec3 L = vs_light_pos - surface_pos; 72 | 73 | float dist = length(L); 74 | float attenuation = pow(max(0.0, 1.0 - dist / light_radius), light_falloff + 1.0); 75 | 76 | L = normalize(L); 77 | 78 | float theta = acos(dot(vs_dir, L)); 79 | 80 | if(theta < halfInner) 81 | attenuation *= 1; 82 | else if(theta < halfOutter) 83 | attenuation *= (halfOutter - theta) / (halfOutter - halfInner); 84 | else 85 | attenuation = 0; 86 | 87 | vec3 N = normalize(normal); 88 | 89 | float NdotL = max(0.0, dot(N, L)); 90 | 91 | return vec4( 92 | vec3(1) * light_color * NdotL * attenuation * light_intensity, 1.0 93 | ); 94 | } 95 | 96 | void main() 97 | { 98 | vec2 screenUV = (ss_pos.xy / ss_pos.w) * 0.5 + 0.5; 99 | vec3 vs_surface_pos = pos_from_depth(screenUV); 100 | 101 | vec4 raw_normal = texture(gbuffer_normal, screenUV); 102 | vec3 vs_normal = raw_normal.xyz * 2.0 - 1.0; 103 | 104 | fragment_output = apply_lighting(vs_normal, vs_surface_pos); 105 | 106 | #ifdef SHADOW 107 | vec4 shadowCoord = shadow_matrix * vec4(vs_surface_pos, 1.0); 108 | shadowCoord = shadowCoord / shadowCoord.w; 109 | fragment_output *= float(shadowCoord.z < texture(shadow_buffer, shadowCoord.xy).x); 110 | #endif 111 | } 112 | 113 | #endif -------------------------------------------------------------------------------- /examples/bin/Resource/Shader/Lambert/SunLight.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #ifdef VERTEX_SHADER 4 | 5 | in vec3 vertex_position; 6 | 7 | out vec3 vs_dir; 8 | out vec3 vs_pos; 9 | out vec4 ss_pos; 10 | 11 | uniform float camera_far = 10000; 12 | 13 | uniform vec3 light_dir; 14 | 15 | uniform mat4 projection_matrix; 16 | uniform mat4 invert_view_matrix; 17 | 18 | void main() 19 | { 20 | vs_dir = normalize(invert_view_matrix * vec4(-light_dir, 0)).xyz; 21 | vs_pos = (inverse(projection_matrix) * vec4(vertex_position.xy, 1.0, 1.0) * camera_far).xyz; 22 | ss_pos = vec4(vertex_position.xyz, 1.0); 23 | gl_Position = ss_pos; 24 | } 25 | 26 | #endif 27 | 28 | #ifdef FRAGMENT_SHADER 29 | 30 | out vec4 fragment_output; 31 | 32 | in vec3 vs_dir; 33 | in vec3 vs_pos; 34 | in vec4 ss_pos; 35 | 36 | uniform vec3 light_color; 37 | uniform float light_intensity; 38 | 39 | // linear depth 40 | uniform sampler2D gbuffer_depth; 41 | // normal, shniness 42 | uniform sampler2D gbuffer_normal; 43 | 44 | #ifdef CSM 45 | 46 | uniform mat4 projection_matrix; 47 | uniform mat4 shadow_matrix[4]; 48 | uniform sampler2DArray shadow_buffer; 49 | 50 | uniform float bias = 0.002; 51 | uniform vec4 shadow_far; 52 | 53 | #endif 54 | 55 | #ifdef SHADOW 56 | 57 | uniform sampler2D shadow_buffer; 58 | uniform mat4 shadow_matrix; 59 | 60 | #endif 61 | 62 | vec3 pos_from_depth(const in vec2 screenUV) 63 | { 64 | float depth = texture(gbuffer_depth, screenUV).r; 65 | vec3 view_ray = vs_pos.xyz; 66 | return view_ray * depth; 67 | } 68 | 69 | vec4 apply_lighting(const in vec3 normal, const in vec3 surface_pos) 70 | { 71 | vec3 L = normalize(vs_dir); 72 | vec3 N = normalize(normal); 73 | 74 | float NdotL = max(0.0, dot(N, L)); 75 | 76 | return vec4( 77 | vec3(1) * light_color * NdotL * light_intensity, 1.0 78 | ); 79 | } 80 | 81 | void main() 82 | { 83 | vec2 screenUV = ss_pos.xy * 0.5 + 0.5; 84 | vec3 vs_surface_pos = pos_from_depth(screenUV); 85 | 86 | vec4 raw_normal = texture(gbuffer_normal, screenUV); 87 | vec3 vs_normal = raw_normal.xyz * 2.0 - 1.0; 88 | 89 | fragment_output = apply_lighting(vs_normal, vs_surface_pos); 90 | 91 | #ifdef CSM 92 | 93 | vec4 pos = projection_matrix * vec4(vs_surface_pos, 1.0); 94 | 95 | int index = 3; 96 | if (pos.z < shadow_far.x) 97 | index = 0; 98 | else if(pos.z < shadow_far.y) 99 | index = 1; 100 | else if(pos.z < shadow_far.z) 101 | index = 2; 102 | 103 | vec4 shadowCoord = shadow_matrix[index] * vec4(vs_surface_pos, 1.0); 104 | shadowCoord = shadowCoord / shadowCoord.w; 105 | vec3 crood = vec3(shadowCoord.x, shadowCoord.y, float(index)); 106 | fragment_output *= shadowCoord.z > 1.0 ? 1.0 : float(shadowCoord.z < texture(shadow_buffer, crood).x); 107 | 108 | #endif 109 | 110 | #ifdef SHADOW 111 | 112 | vec4 shadowCoord = shadow_matrix * vec4(vs_surface_pos, 1.0); 113 | shadowCoord = shadowCoord / shadowCoord.w; 114 | fragment_output *= shadowCoord.z > 1.0 ? 1.0 : float(shadowCoord.z < texture(shadow_buffer, shadowCoord.xy).x); 115 | 116 | #endif 117 | } 118 | 119 | #endif -------------------------------------------------------------------------------- /examples/bin/demo.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | demo 9 | CFBundleIconFile 10 | demo.icns 11 | CFBundleIdentifier 12 | com.sindney.demo 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | demo 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0 21 | CFBundleVersion 22 | 0 23 | NSHighResolutionCapable 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/bin/demo.app/Contents/Resources/demo.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/examples/bin/demo.app/Contents/Resources/demo.icns -------------------------------------------------------------------------------- /examples/bin/readme.txt: -------------------------------------------------------------------------------- 1 | On osx, move Resource folder to demo.app/Contents/Resources folder. -------------------------------------------------------------------------------- /screenshots/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/screenshots/1.jpg -------------------------------------------------------------------------------- /screenshots/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindney/fury3d/a5880af615c3225e279eb63a9193c7ca8b5fcf49/screenshots/2.jpg --------------------------------------------------------------------------------