diff --git a/Apps/GreenWorld/GreenWorldInterface.cpp b/Apps/GreenWorld/GreenWorldInterface.cpp index f6eeb001..9fe0c97c 100644 --- a/Apps/GreenWorld/GreenWorldInterface.cpp +++ b/Apps/GreenWorld/GreenWorldInterface.cpp @@ -130,10 +130,10 @@ namespace GW void GreenWorldInterface::InitUI() { + _windowAlphaValue = 0.65; LoadCustomFont("../Res/Assets/Fonts/JetBrainsMono-Medium.ttf", 19); SetDarkThemeColors(); CalcElementSizes(); - _windowAlphaValue = 0.65; } void GreenWorldInterface::AddElements() diff --git a/Apps/Liquefied/LiquefiedApp.cpp b/Apps/Liquefied/LiquefiedApp.cpp index 7cf3d7f0..c8ff7a7d 100644 --- a/Apps/Liquefied/LiquefiedApp.cpp +++ b/Apps/Liquefied/LiquefiedApp.cpp @@ -10,7 +10,7 @@ namespace Liq Engine::ResourceManager::LoadShader("SpriteShader", "../Res/Shader/GreenWorld/Sprite_VS.glsl", "../Res/Shader/GreenWorld/Sprite_FS.glsl"); //Texture - Engine::ResourceManager::LoadTextureToBuffer("BG_Texture", "../Res/Assets/Textures/Liquefied/Dark_Squares.jpg"); + Engine::ResourceManager::LoadTextureToBuffer("BG_Texture", "../Res/Assets/Textures/Liquefied/Dark_Squares_1500.jpg"); } Engine::uint32 LiquefiedApp::InitModules() @@ -32,9 +32,23 @@ namespace Liq //Create UI _interface = Engine::MakeScope(); + //Create fluid simulator + _fluidSimulator = Engine::MakeScope(); + return EXIT_SUCCESS; } + void LiquefiedApp::VisualizeSmoke() + { + float* smokeField = _fluidSimulator->GetSmokeField(); + + //Iterate over smoke field + + //Set color at pixel(x,y) to the value of the vector field at (x,y) + + //Using scientific color scheme + } + // ----- Public ----- LiquefiedApp::LiquefiedApp() @@ -73,6 +87,13 @@ namespace Liq Engine::RenderManager::PrepareFrame(); } + { + Engine::PROFILE_SCOPE("Simulate liquid"); + + _fluidSimulator->TimeStep(); + VisualizeSmoke(); + } + { Engine::PROFILE_SCOPE("Render pixels"); diff --git a/Apps/Liquefied/LiquefiedApp.hpp b/Apps/Liquefied/LiquefiedApp.hpp index 6266ef89..af951f16 100644 --- a/Apps/Liquefied/LiquefiedApp.hpp +++ b/Apps/Liquefied/LiquefiedApp.hpp @@ -8,11 +8,13 @@ namespace Liq class LiquefiedApp final : public Engine::App { private: - Engine::PixelRenderer* _pixelRenderer = nullptr; - Engine::Scope _interface; + Engine::PixelRenderer* _pixelRenderer = nullptr; + Engine::Scope _interface; + Engine::Scope _fluidSimulator; void LoadResources() override; Engine::uint32 InitModules() override; + void VisualizeSmoke(); public: LiquefiedApp(); diff --git a/Apps/Liquefied/LiquefiedInterface.cpp b/Apps/Liquefied/LiquefiedInterface.cpp index f92c0391..cfcd2615 100644 --- a/Apps/Liquefied/LiquefiedInterface.cpp +++ b/Apps/Liquefied/LiquefiedInterface.cpp @@ -13,12 +13,6 @@ namespace Liq ImGui::MenuItem("Show overlay", "", &Engine::UIParams::showOverlay); ImGui::EndMenu(); } - - if(ImGui::BeginMenu("Rendering")) - { - ImGui::MenuItem("Wireframe-Mode", "", &Engine::UIParams::wireframeRendering); - ImGui::EndMenu(); - } } ImGui::EndMainMenuBar(); } @@ -50,6 +44,19 @@ namespace Liq ImGui::End(); } + void LiquefiedInterface::AddBufferBar() const + { + ImGui::SetNextWindowBgAlpha(0.9f); + ImGui::SetNextWindowPos(_bufferBarPos, ImGuiCond_Always); + ImGui::SetNextWindowSize(_bufferBarSize); + + if(ImGui::Begin("Bufferbar", nullptr, _windowFlags)) + { + // ... + } + ImGui::End(); + } + // ----- Public ----- LiquefiedInterface::LiquefiedInterface() @@ -67,7 +74,7 @@ namespace Liq void LiquefiedInterface::AddElements() { - ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f); //Discard old plotting data every 120 frames if(Engine::Window::GetFrameCounter() > 120) @@ -76,6 +83,7 @@ namespace Liq } AddMenuBar(); + AddBufferBar(); if(Engine::UIParams::showOverlay) { diff --git a/Apps/Liquefied/LiquefiedInterface.hpp b/Apps/Liquefied/LiquefiedInterface.hpp index b13945c9..370bc257 100644 --- a/Apps/Liquefied/LiquefiedInterface.hpp +++ b/Apps/Liquefied/LiquefiedInterface.hpp @@ -7,8 +7,12 @@ namespace Liq class LiquefiedInterface final : public Engine::Interface { private: + ImVec2 _bufferBarSize = ImVec2((float)Engine::WindowParams::WIDTH - _sidebarWidth, 80.0f - _menuBarHeight); + ImVec2 _bufferBarPos = ImVec2(0.0f, _menuBarHeight); + void AddMenuBar() const; void AddSideBar() const; + void AddBufferBar() const; public: LiquefiedInterface(); diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f179c60..f3ad0f54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ target_include_directories(SalinityGL PUBLIC Engine/Application) target_include_directories(SalinityGL PUBLIC Engine/Core) target_include_directories(SalinityGL PUBLIC Engine/Debug) target_include_directories(SalinityGL PUBLIC Engine/Physics/CellularAutomata) +target_include_directories(SalinityGL PUBLIC Engine/Physics/FluidSimulation) target_include_directories(SalinityGL PUBLIC Engine/Rendering/Buffers) target_include_directories(SalinityGL PUBLIC Engine/Rendering/Camera) target_include_directories(SalinityGL PUBLIC Engine/Rendering/Renderables) diff --git a/Engine/Application/GlobalParams.hpp b/Engine/Application/GlobalParams.hpp index 309e0f97..68e8a0ac 100644 --- a/Engine/Application/GlobalParams.hpp +++ b/Engine/Application/GlobalParams.hpp @@ -84,12 +84,6 @@ namespace Engine } }; - #define COLOR_WHITE glm::vec3(1.0f, 1.0f, 1.0f) - #define COLOR_BLACK glm::vec3(1.0f, 1.0f, 1.0f) - #define COLOR_RED glm::vec3(1.0f, 0.0f, 0.0f) - #define COLOR_GREEN glm::vec3(0.0f, 1.0f, 0.0f) - #define COLOR_BLUE glm::vec3(0.0f, 0.0f, 1.0f) - // ####################################################################################################### // ############################################### GreenWorld ############################################ // ####################################################################################################### @@ -152,5 +146,10 @@ namespace Engine // ############################################### Liquefied ############################################# // ####################################################################################################### - //Nothing here + struct LiquiefiedParams + { + inline static constexpr uint32 SIMULATION_WIDTH = 1500; + inline static constexpr uint32 SIMULATION_HEIGHT = 1000; + inline static constexpr uint32 LIQUID_NUM_CELLS = SIMULATION_WIDTH * SIMULATION_HEIGHT; + }; } \ No newline at end of file diff --git a/Engine/Core/Types.hpp b/Engine/Core/Types.hpp index dc2fc3cd..c6bc1a5f 100644 --- a/Engine/Core/Types.hpp +++ b/Engine/Core/Types.hpp @@ -33,4 +33,10 @@ namespace Engine typedef uint16_t uint16; typedef uint32_t uint32; typedef uint64_t uint64; + + #define COLOR_WHITE glm::vec3(1.0f, 1.0f, 1.0f) + #define COLOR_BLACK glm::vec3(1.0f, 1.0f, 1.0f) + #define COLOR_RED glm::vec3(1.0f, 0.0f, 0.0f) + #define COLOR_GREEN glm::vec3(0.0f, 1.0f, 0.0f) + #define COLOR_BLUE glm::vec3(0.0f, 0.0f, 1.0f) } \ No newline at end of file diff --git a/Engine/Core/Utility.cpp b/Engine/Core/Utility.cpp new file mode 100644 index 00000000..0a73575a --- /dev/null +++ b/Engine/Core/Utility.cpp @@ -0,0 +1,28 @@ +#include "Utility.hpp" + +namespace Engine +{ + // ----- Public ----- + + glm::vec3 Utility::GetScienticColor(float value, const float min, const float max) + { + value = fminf(fmaxf(value, min), max - 0.0001f); + const float diff = max - min; + value = diff == 0.0f ? 0.5f : (value - min) / diff; + const float divider = 0.25f; + const float number = floorf(value / divider); + const float pos = (value - number * divider) / divider; + + glm::vec3 retVec{0.0f}; + switch(number) + { + case 0 : retVec.x = 0.0f; retVec.y = pos; retVec.z = 1.0f; break; + case 1 : retVec.x = 0.0f; retVec.y = 1.0f; retVec.z = 1.0f - pos; break; + case 2 : retVec.x = pos; retVec.y = 1.0f; retVec.z = 0.0f; break; + case 3 : retVec.x = 1.0f; retVec.y = 1.0f; retVec.z = 0.0f; break; + default: break; + } + + return retVec; + } +} \ No newline at end of file diff --git a/Engine/Core/Utility.hpp b/Engine/Core/Utility.hpp new file mode 100644 index 00000000..be466648 --- /dev/null +++ b/Engine/Core/Utility.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "glm.hpp" + +#include + +namespace Engine +{ + class Utility + { + public: + Utility() = delete; + static glm::vec3 GetScienticColor(float value, float min, float max); + }; +} \ No newline at end of file diff --git a/Engine/Engine.hpp b/Engine/Engine.hpp index 38bff1fd..645e53a3 100644 --- a/Engine/Engine.hpp +++ b/Engine/Engine.hpp @@ -26,4 +26,7 @@ #include "SpriteRenderer.hpp" #include "WaterRenderer.hpp" #include "ParticleRenderer.hpp" -#include "CellManager.hpp" \ No newline at end of file + +// ----- Physics ----- +#include "CellManager.hpp" +#include "FluidSimulator.hpp" \ No newline at end of file diff --git a/Engine/Application/CellTypes.def b/Engine/Physics/CellularAutomata/CellTypes.def similarity index 100% rename from Engine/Application/CellTypes.def rename to Engine/Physics/CellularAutomata/CellTypes.def diff --git a/Engine/Physics/FluidSimulation/FluidSimulator.cpp b/Engine/Physics/FluidSimulation/FluidSimulator.cpp new file mode 100644 index 00000000..3a03686a --- /dev/null +++ b/Engine/Physics/FluidSimulation/FluidSimulator.cpp @@ -0,0 +1,58 @@ +#include "FluidSimulator.hpp" + +namespace Engine +{ + // ----- Private ----- + + /* Applies forces to the liquid - just gravity in our case */ + void FluidSimulator::AddForces(float dt) + { + + } + + /* Projection calculates and applies the right amount of pressure to make the * + * velocity field divergence-free and also enforces solid wall boundary conditions. */ + void FluidSimulator::Project(float dt) + { + + } + + /* Advection moves the quantity, or molecules, or particles, along the velocity field. */ + void FluidSimulator::AdvectVelocity(float dt) + { + + } + + /* To visualize the flow, we store a density or dye value at the center of each cell * + * and advect it like the velocity field. */ + void FluidSimulator::AdvectSmoke(float dt) + { + + } + + // ----- Public ----- + + FluidSimulator::FluidSimulator() + { + + } + + FluidSimulator::~FluidSimulator() + { + + } + + void FluidSimulator::TimeStep() + { + float dt = (float)Window::GetDeltaTime(); + AddForces(dt); + Project(dt); + AdvectVelocity(dt); + AdvectSmoke(dt); + } + + float* FluidSimulator::GetSmokeField() + { + return &_smokeField[0]; + } +} \ No newline at end of file diff --git a/Engine/Physics/FluidSimulation/FluidSimulator.hpp b/Engine/Physics/FluidSimulation/FluidSimulator.hpp new file mode 100644 index 00000000..878eb407 --- /dev/null +++ b/Engine/Physics/FluidSimulation/FluidSimulator.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "Window.hpp" +#include "GlobalParams.hpp" + +#define at(x, y) ((x) * Liquiedfied::Params::SIMULATION_HEIGHT + (y)) + +namespace Engine +{ + class FluidSimulator + { + private: + float _gravity = -9.81f; + float _velocityField[LiquiefiedParams::LIQUID_NUM_CELLS] = {0}; + float _smokeField[LiquiefiedParams::LIQUID_NUM_CELLS] = {0}; + + void AddForces(float dt); + void Project(float dt); + void AdvectVelocity(float dt); + void AdvectSmoke(float dt); + + public: + FluidSimulator(); + ~FluidSimulator(); + void TimeStep(); + float* GetSmokeField(); + }; +} \ No newline at end of file diff --git a/Engine/Rendering/Resources/Texture.cpp b/Engine/Rendering/Resources/Texture.cpp index 88356d4b..109727c6 100644 --- a/Engine/Rendering/Resources/Texture.cpp +++ b/Engine/Rendering/Resources/Texture.cpp @@ -203,7 +203,7 @@ namespace Engine void Texture::CommitModifications() const { Bind(); - GLCall(glTexImage2D(GL_TEXTURE_2D, 0, _format, _width, _height, 0, _format, GL_UNSIGNED_BYTE, _imgBuffer)); + GLCall(glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, _width, _height, GL_RGB, GL_UNSIGNED_BYTE, _imgBuffer)); Unbind(); } diff --git a/Res/Assets/Textures/Liquefied/Dark_Squares_1500.jpg b/Res/Assets/Textures/Liquefied/Dark_Squares_1500.jpg new file mode 100644 index 00000000..f090fece Binary files /dev/null and b/Res/Assets/Textures/Liquefied/Dark_Squares_1500.jpg differ