diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 57b349ed..8d7a7b89 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -34,11 +34,12 @@ #include "src/Misc/WindowTheming.h" -const std::string WindowTitle = "Nuake Editor"; +std::string WindowTitle = "Nuake Editor "; int ApplicationMain(int argc, char* argv[]) { - bool playMode = false; + using namespace Nuake; + std::string projectPath = ""; Vector2 editorResolution = Vector2(1280, 720); @@ -48,15 +49,6 @@ int ApplicationMain(int argc, char* argv[]) char* arg = argv[i]; std::string args = std::string(arg); - if (args == "--play") - { - if (argc > 2) - { - projectPath = std::string(argv[i + 1]); - } - playMode = true; - } - if (args == "--resolution") { if (argc >= i + 1) @@ -84,7 +76,7 @@ int ApplicationMain(int argc, char* argv[]) } bool shouldLoadProject = false; - if (!playMode && argc > 1) + if (argc > 1) { shouldLoadProject = true; projectPath = std::string(argv[1]); @@ -136,8 +128,8 @@ int ApplicationMain(int argc, char* argv[]) WindowTheming::SetWindowDarkMode(window); - Nuake::EditorInterface editor; - editor.BuildFonts(); + Nuake::EditorInterface editor; + editor.BuildFonts(); if (monitorIdx != -1) { @@ -173,45 +165,45 @@ int ApplicationMain(int argc, char* argv[]) Nuake::Engine::Tick(); Nuake::Engine::Draw(); - Timestep ts = Nuake::Engine::GetTimestep(); + Timestep ts = Nuake::Engine::GetTimestep(); - Nuake::Vector2 WindowSize = window->GetSize(); - glViewport(0, 0, WindowSize.x, WindowSize.y); - Nuake::Renderer2D::BeginDraw(WindowSize); + Nuake::Vector2 WindowSize = window->GetSize(); + glViewport(0, 0, WindowSize.x, WindowSize.y); + Nuake::Renderer2D::BeginDraw(WindowSize); - auto sceneFramebuffer = window->GetFrameBuffer(); - sceneFramebuffer->Bind(); + auto sceneFramebuffer = window->GetFrameBuffer(); + sceneFramebuffer->Bind(); + { + Ref currentScene = Nuake::Engine::GetCurrentScene(); + Ref camera; + if (currentScene) { - Ref currentScene = Nuake::Engine::GetCurrentScene(); - Ref camera; - if (currentScene) + camera = currentScene->m_EditorCamera; + } + + if (currentScene && !Nuake::Engine::IsPlayMode()) + { + glEnable(GL_LINE_SMOOTH); + + if (editor.ShouldDrawAxis()) { - camera = currentScene->m_EditorCamera; + //gizmoDrawer.DrawAxis(currentScene); } - if (currentScene && !Nuake::Engine::IsPlayMode()) + if (editor.ShouldDrawCollision()) { - glEnable(GL_LINE_SMOOTH); - - if (editor.ShouldDrawAxis()) - { - //gizmoDrawer.DrawAxis(currentScene); - } - - if (editor.ShouldDrawCollision()) - { - gizmoDrawer.DrawGizmos(currentScene); - } + gizmoDrawer.DrawGizmos(currentScene); } } - sceneFramebuffer->Unbind(); - - editor.Update(ts); - editor.Draw(); - - Nuake::Engine::EndDraw(); } + sceneFramebuffer->Unbind(); + + editor.Update(ts); + editor.Draw(); + + Nuake::Engine::EndDraw(); } + Nuake::Engine::Close(); diff --git a/Editor/src/ComponentsPanel/QuakeMapPanel.h b/Editor/src/ComponentsPanel/QuakeMapPanel.h index 7269ba76..48be8510 100644 --- a/Editor/src/ComponentsPanel/QuakeMapPanel.h +++ b/Editor/src/ComponentsPanel/QuakeMapPanel.h @@ -4,6 +4,7 @@ #include "src/Scene/Systems/QuakeMapBuilder.h" #include + class QuakeMapPanel : ComponentPanel { public: diff --git a/Editor/src/Misc/GizmoDrawer.cpp b/Editor/src/Misc/GizmoDrawer.cpp index c883d3de..83a466a0 100644 --- a/Editor/src/Misc/GizmoDrawer.cpp +++ b/Editor/src/Misc/GizmoDrawer.cpp @@ -19,6 +19,7 @@ #include #include #include +#include GizmoDrawer::GizmoDrawer() { @@ -367,6 +368,26 @@ void GizmoDrawer::DrawGizmos(Ref scene) renderList.AddToRenderList(Renderer::QuadMesh, particleTransform); } + renderList.Flush(gizmoShader, true); + + auto audioView = scene->m_Registry.view(); + for (auto e : audioView) + { + gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("resources/Gizmos/speaker.png").get()); + auto [transformComponent, audioEmitterComponent] = scene->m_Registry.get(e); + + auto initialTransform = transformComponent.GetGlobalTransform(); + Matrix4 transform = initialTransform; + transform = glm::inverse(scene->m_EditorCamera->GetTransform()); + + // Translation + const Vector3& globalPosition = transformComponent.GetGlobalPosition(); + transform[3] = initialTransform[3]; + transform = glm::scale(transform, Vector3(0.5f, 0.5f, 0.5f)); + + renderList.AddToRenderList(Renderer::QuadMesh, transform); + } + renderList.Flush(gizmoShader, true); RenderCommand::Enable(RendererEnum::DEPTH_TEST); diff --git a/Editor/src/Windows/EditorSelectionPanel.cpp b/Editor/src/Windows/EditorSelectionPanel.cpp index af20949f..f7c5c74d 100644 --- a/Editor/src/Windows/EditorSelectionPanel.cpp +++ b/Editor/src/Windows/EditorSelectionPanel.cpp @@ -8,12 +8,9 @@ #include #include #include + #include -#include "src/Scene/Components/WrenScriptComponent.h" -#include "src/Scene/Components/ParticleEmitterComponent.h" - - EditorSelectionPanel::EditorSelectionPanel() { } @@ -118,9 +115,10 @@ void EditorSelectionPanel::DrawEntity(Nuake::Entity entity) void EditorSelectionPanel::DrawAddComponentMenu(Nuake::Entity entity) { - if (entity.HasComponent()) + using namespace Nuake; + if (entity.HasComponent()) { - auto& entityName = entity.GetComponent().Name; + auto& entityName = entity.GetComponent().Name; ImGuiTextSTD("##Name", entityName); ImGui::SameLine(); @@ -129,27 +127,29 @@ void EditorSelectionPanel::DrawAddComponentMenu(Nuake::Entity entity) if (ImGui::BeginPopup("ComponentPopup")) { - MenuItemComponent("Wren Script", Nuake::WrenScriptComponent) - MenuItemComponent("Camera", Nuake::CameraComponent) - MenuItemComponent("Light", Nuake::LightComponent) + MenuItemComponent("Wren Script", WrenScriptComponent); + MenuItemComponent("Camera", CameraComponent); + MenuItemComponent("Light", LightComponent); ImGui::Separator(); - MenuItemComponent("Model", Nuake::ModelComponent) - MenuItemComponent("Skinned Model", Nuake::SkinnedModelComponent) - MenuItemComponent("Bone", Nuake::BoneComponent) + MenuItemComponent("Model", ModelComponent); + MenuItemComponent("Skinned Model", SkinnedModelComponent); + MenuItemComponent("Bone", BoneComponent) ImGui::Separator(); - MenuItemComponent("Sprite", Nuake::SpriteComponent) - MenuItemComponent("Particle Emitter", Nuake::ParticleEmitterComponent) + MenuItemComponent("Sprite", SpriteComponent) + MenuItemComponent("Particle Emitter", ParticleEmitterComponent) ImGui::Separator(); - MenuItemComponent("Character Controller", Nuake::CharacterControllerComponent) - MenuItemComponent("Rigid body", Nuake::RigidBodyComponent) + MenuItemComponent("Character Controller", CharacterControllerComponent) + MenuItemComponent("Rigid body", RigidBodyComponent) ImGui::Separator(); - MenuItemComponent("Box collider", Nuake::BoxColliderComponent) - MenuItemComponent("Capsule collider", Nuake::CapsuleColliderComponent) - MenuItemComponent("Cylinder collider", Nuake::CylinderColliderComponent) - MenuItemComponent("Sphere collider", Nuake::SphereColliderComponent) - MenuItemComponent("Mesh collider", Nuake::MeshColliderComponent) + MenuItemComponent("Box collider", BoxColliderComponent) + MenuItemComponent("Capsule collider", CapsuleColliderComponent) + MenuItemComponent("Cylinder collider", CylinderColliderComponent) + MenuItemComponent("Sphere collider", SphereColliderComponent) + MenuItemComponent("Mesh collider", MeshColliderComponent) ImGui::Separator(); - MenuItemComponent("Quake map", Nuake::QuakeMapComponent) + MenuItemComponent("Quake map", QuakeMapComponent); + ImGui::Separator(); + MenuItemComponent("Audio Emitter", AudioEmitterComponent); ImGui::EndPopup(); } ImGui::Separator(); diff --git a/Nuake/src/Audio/AudioManager.cpp b/Nuake/src/Audio/AudioManager.cpp index d8672ea6..6702315e 100644 --- a/Nuake/src/Audio/AudioManager.cpp +++ b/Nuake/src/Audio/AudioManager.cpp @@ -1,32 +1,43 @@ #include "AudioManager.h" +#include "src/Core/Logger.h" +#include "src/Core/FileSystem.h" #include #include "soloud_speech.h" #include "soloud_thread.h" +#include -namespace Nuake -{ - void AudioManager::Initialize() + +namespace Nuake { + + AudioManager::AudioManager() : + m_AudioThreadRunning(true) { - _soloud = CreateRef(); - _soloud->init(); - - _audioThreadRunning = false; - _audioThread = std::thread(&AudioManager::AudioThreadLoop, this); } AudioManager::~AudioManager() { Deinitialize(); - _audioThreadRunning = false; - _audioThread.join(); + m_AudioThreadRunning = false; + m_AudioThread.join(); } + void AudioManager::Initialize() + { + m_Soloud = CreateRef(); + + // TODO: Sample rate, back end, buffer size, flags. + m_Soloud->init(); + + m_AudioThread = std::thread(&AudioManager::AudioThreadLoop, this); + + Logger::Log("Audio manager initialized", "audio", VERBOSE); + } void AudioManager::Deinitialize() { - _soloud->deinit(); + m_Soloud->deinit(); } void AudioManager::PlayTTS(const std::string& text) @@ -34,11 +45,50 @@ namespace Nuake } + void AudioManager::QueueWavAudio(const std::string& filePath) + { + // Acquire mutex lock and push to queue + const std::lock_guard lock(m_AudioQueueMutex); + + // Check if file exists and load + const bool fileExists = FileSystem::FileExists(filePath, true); + if (fileExists && !IsWavLoaded(filePath)) + { + LoadWavAudio(filePath); + } + + m_AudioQueue.push({ filePath }); + } + + bool AudioManager::IsWavLoaded(const std::string& filePath) const + { + return m_WavSamples.find(filePath) != m_WavSamples.end(); + } + + void AudioManager::LoadWavAudio(const std::string& filePath) + { + m_WavSamples[filePath] = SoLoud::Wav(); + m_WavSamples[filePath].load(filePath.c_str()); + } + void AudioManager::AudioThreadLoop() { - while(_audioThreadRunning) + while(m_AudioThreadRunning) { - + // Acquire mutex lock + const std::lock_guard lock(m_AudioQueueMutex); + + // Check if we have audio queued + while (!m_AudioQueue.empty()) + { + auto& currentAudio = m_AudioQueue.front(); + + // If file exists, play it + m_Soloud->play(m_WavSamples[currentAudio.audioFile]); + + // Remove item from queue. + m_AudioQueue.pop(); + } } } } \ No newline at end of file diff --git a/Nuake/src/Audio/AudioManager.h b/Nuake/src/Audio/AudioManager.h index a60ab612..d2f0fc16 100644 --- a/Nuake/src/Audio/AudioManager.h +++ b/Nuake/src/Audio/AudioManager.h @@ -10,21 +10,36 @@ namespace SoLoud class AudioSource; } +// Temp code +struct audioQueueRequest +{ + std::string audioFile; +}; + +namespace SoLoud +{ + class Wav; +} + namespace Nuake { // This is a singleton that manages everything for audio. class AudioManager { private: - Ref _soloud; - - bool _audioThreadRunning; - std::thread _audioThread; - std::mutex _audioMutex; - const int MAX_VOICE_COUNT = 32; + + Ref m_Soloud; + + bool m_AudioThreadRunning; + std::thread m_AudioThread; + std::mutex m_AudioQueueMutex; + std::atomic m_AudioQueued = { false }; + std::queue m_AudioQueue; + + std::unordered_map m_WavSamples; public: - AudioManager() = default; + AudioManager(); ~AudioManager(); static AudioManager& Get() @@ -42,6 +57,9 @@ namespace Nuake void PlayTTS(const std::string& text); + void QueueWavAudio(const std::string& filePath); + bool IsWavLoaded(const std::string& filePath) const; + void LoadWavAudio(const std::string& filePath); private: void AudioThreadLoop(); }; diff --git a/Nuake/src/Audio/AudioSource.h b/Nuake/src/Audio/AudioSource.h index 7d4b513f..775983dc 100644 --- a/Nuake/src/Audio/AudioSource.h +++ b/Nuake/src/Audio/AudioSource.h @@ -5,6 +5,8 @@ namespace Nuake class AudioSource { private: + bool m_Loop = false; + bool m_Is3D = false; public: AudioSource() = default; diff --git a/Nuake/src/Core/Core.h b/Nuake/src/Core/Core.h index 9b73304f..816c6a6d 100644 --- a/Nuake/src/Core/Core.h +++ b/Nuake/src/Core/Core.h @@ -4,6 +4,7 @@ #include #include #include +#include #define ASSERT(x) if (!(x)) assert(false) diff --git a/Nuake/src/Scene/Components/AudioEmitterComponent.h b/Nuake/src/Scene/Components/AudioEmitterComponent.h new file mode 100644 index 00000000..1687f9de --- /dev/null +++ b/Nuake/src/Scene/Components/AudioEmitterComponent.h @@ -0,0 +1,17 @@ +#pragma once +#include "src/Core/Core.h" +#include "src/Resource/Serializable.h" + +namespace Nuake { + + class AudioEmitterComponent + { + public: + float Volume = 1.0f; + float Pan = 0.0f; + float PlaybackSpeed = 1.0f; + + json Serialize(); + bool Deserialize(const json& j); + }; +} diff --git a/Nuake/src/Scene/Components/BoxCollider.h b/Nuake/src/Scene/Components/BoxCollider.h index dd67bf08..f1fb1f84 100644 --- a/Nuake/src/Scene/Components/BoxCollider.h +++ b/Nuake/src/Scene/Components/BoxCollider.h @@ -3,6 +3,7 @@ #include "src/Core/Core.h" namespace Nuake { + class BoxColliderComponent { public: diff --git a/Nuake/src/Scene/Components/Components.h b/Nuake/src/Scene/Components/Components.h index d47b0044..b2962548 100644 --- a/Nuake/src/Scene/Components/Components.h +++ b/Nuake/src/Scene/Components/Components.h @@ -17,7 +17,11 @@ #include "CylinderColliderComponent.h" #include "NativeScriptComponent.h" +#include "ParticleEmitterComponent.h" + #include "ParentComponent.h" #include "NameComponent.h" #include "BoxCollider.h" +#include "AudioEmitterComponent.h" +#include "WrenScriptComponent.h" #include "../Entities/Entity.h" diff --git a/premake5.lua b/premake5.lua index 31c388ce..cbf046e0 100644 --- a/premake5.lua +++ b/premake5.lua @@ -4,7 +4,8 @@ workspace "Nuake" configurations { "Debug", - "Release" + "Release", + "Dist" } outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" @@ -14,6 +15,7 @@ include "Nuake/dependencies/assimp_p5.lua" include "Nuake/dependencies/freetype_p5.lua" include "Nuake/dependencies/jolt_p5.lua" include "Nuake/dependencies/soloud_p5.lua" +include "Nuake/dependencies/optick_p5.lua" project "Nuake" location "Nuake" @@ -26,6 +28,7 @@ project "Nuake" "_MBCS" } + targetdir ("bin/" .. outputdir .. "/%{prj.name}") objdir ("bin-int/" .. outputdir .. "/%{prj.name}") @@ -72,15 +75,30 @@ project "Nuake" filter "system:windows" cppdialect "C++17" staticruntime "On" + defines { + "NK_WIN" + } filter "configurations:Debug" runtime "Debug" symbols "on" + defines + { + "NK_DEBUG" + } filter "configurations:Release" runtime "Release" optimize "on" + filter "configurations:Dist" + runtime "Release" + optimize "on" + defines + { + "NK_DIST" + } + project "NuakeRuntime" location "Runtime" kind "ConsoleApp" @@ -138,14 +156,28 @@ project "NuakeRuntime" filter "system:windows" cppdialect "C++17" staticruntime "On" + defines { + "NK_WIN" + } filter "configurations:Debug" runtime "Debug" symbols "on" + defines { + "NK_DEBUG" + } filter "configurations:Release" + kind "WindowedApp" runtime "Release" optimize "on" + defines { + "NK_DIST", + "WIN32_LEAN_AND_MEAN" + } + entrypoint "WinMainCRTStartup" + flags { "WinMain" } + buildoptions { "-mwindows"} -- copy a file from the objects directory to the target directory postbuildcommands { @@ -161,11 +193,6 @@ project "Editor" objdir ("bin-int/" .. outputdir .. "/%{prj.name}") debugdir ("%{prj.name}") - defines - { - - } - files { "%{prj.name}/Editor.cpp", @@ -227,6 +254,18 @@ project "Editor" runtime "Release" optimize "on" + filter "configurations:Dist" + kind "WindowedApp" + runtime "Release" + optimize "on" + defines { + "NK_DIST", + "WIN32_LEAN_AND_MEAN" + } + entrypoint "WinMainCRTStartup" + flags { "WinMain" } + buildoptions { "-mwindows"} + -- copy a file from the objects directory to the target directory postbuildcommands { --"{COPY} "Nuake/dependencies/GLFW/lib-vc2019/glfw3.dll" " .. "./bin/" .. outputdir .. "/%{prj.name}/glfw3.dll"