diff --git a/.gitmodules b/.gitmodules index 939033f..3e0ff9b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,3 @@ -[submodule "src/dependency/bx"] - path = src/dependency/bx - url = https://github.com/bkaradzic/bx -[submodule "src/dependency/bgfx"] - path = src/dependency/bgfx - url = https://github.com/bkaradzic/bgfx -[submodule "src/dependency/bimg"] - path = src/dependency/bimg - url = https://github.com/bkaradzic/bimg [submodule "src/dependency/bgfx.cmake"] path = src/dependency/bgfx.cmake url = https://github.com/bkaradzic/bgfx.cmake diff --git a/src/engine/Shared.h b/src/engine/Shared.h index 6669f45..72a08b5 100644 --- a/src/engine/Shared.h +++ b/src/engine/Shared.h @@ -1,5 +1,6 @@ #pragma once #include +#include struct SharedWindowData { @@ -8,6 +9,16 @@ struct SharedWindowData int32_t WindowHeight = 1080; }; +struct FileChangeNotification +{ + wchar_t FileName[128]{0}; +}; + +struct SharedDevData +{ + bx::SpScUnboundedQueueT* ShaderChangeQueue; +}; + struct GameData { void* PermanentStorage = nullptr; @@ -16,6 +27,7 @@ struct GameData struct SharedData { + SharedDevData Dev; SharedWindowData Window; GameData Game; }; diff --git a/src/engine/main.cpp b/src/engine/main.cpp index 8e21251..216fd9f 100644 --- a/src/engine/main.cpp +++ b/src/engine/main.cpp @@ -1,3 +1,6 @@ +#include +#include +#include #define WIN32_LEAN_AND_MEAN #include #undef min @@ -5,6 +8,8 @@ #include #include +#include +#include #include "Shared.h" #include "Window.h" @@ -21,16 +26,31 @@ constexpr const char* DLLPath = "libPuzGame.dll"; constexpr const wchar_t* DLLWatch = L"cmake-build\\libPuzGame2.dll"; #endif +namespace +{ + bx::AllocatorI* defaultAllocator = new bx::DefaultAllocator{}; +} + +enum class FileChangeType +{ + DLL, + Shader, + CompiledShader, +}; + struct FileWatcherData { - bool Change = false; + bx::SpScUnboundedQueueT ShaderQueue{defaultAllocator}; + bx::SpScUnboundedQueueT DLLQueue{defaultAllocator}; }; struct DevelopmentData { uint8_t FileChangeBuffer[1024]{ 0 }; HMODULE GameLib = NULL; - HANDLE hDevDir = NULL; + HANDLE DevDir = NULL; + HANDLE ShaderDir = NULL; + HANDLE CompiledShaderDir = NULL; FileWatcherData FileWatcher; }; @@ -49,34 +69,54 @@ namespace Shutdown ShutdownFunc; } -unsigned long FileWatcherThread(void* data) +void FileChangeCheck(HANDLE dirHandle, FileChangeType changeType, const wchar_t* compName = nullptr) { DWORD bytesReturned = 0; - bool isRunning = DevData.hDevDir; + bx::memSet(DevData.FileChangeBuffer, 0, sizeof(DevData.FileChangeBuffer)); + if (ReadDirectoryChangesW(dirHandle, DevData.FileChangeBuffer, sizeof(DevData.FileChangeBuffer), true, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE, &bytesReturned, NULL, NULL)) + { + uint32_t offset = 0; + while (true) + { + FILE_NOTIFY_INFORMATION* notifyData = reinterpret_cast(&DevData.FileChangeBuffer[offset]); + + if (notifyData->Action == FILE_ACTION_ADDED || notifyData->Action == FILE_ACTION_MODIFIED || notifyData->Action == FILE_ACTION_RENAMED_NEW_NAME) + { + if (compName == nullptr || wcscmp(notifyData->FileName, compName) == 0) + { + FileChangeNotification notif; + wcscpy(notif.FileName, notifyData->FileName); + if (changeType == FileChangeType::DLL) + { + DevData.FileWatcher.DLLQueue.push(¬if); + } + else if (changeType == FileChangeType::Shader) + { + std::system("../shadercompile.bat"); + } + else if (changeType == FileChangeType::CompiledShader) + { + DevData.FileWatcher.ShaderQueue.push(¬if); + } + printf("detected file change of type %u!\n", changeType); + wprintf(L"%s\n", notifyData->FileName); + } + } + + if (notifyData->NextEntryOffset == 0) break; + offset += notifyData->NextEntryOffset; + } + } +} + +unsigned long FileWatcherThread(void* data) +{ + bool isRunning = DevData.DevDir; while (isRunning) { - bx::memSet(DevData.FileChangeBuffer, 0, sizeof(DevData.FileChangeBuffer)); - if (ReadDirectoryChangesW(DevData.hDevDir, DevData.FileChangeBuffer, sizeof(DevData.FileChangeBuffer), true, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE, &bytesReturned, NULL, NULL)) - { - uint32_t offset = 0; - while (true) - { - FILE_NOTIFY_INFORMATION* notifyData = reinterpret_cast(&DevData.FileChangeBuffer[offset]); - // wprintf(L"Change: %ls\n", notifyData->FileName); - - if (notifyData->Action == FILE_ACTION_ADDED || notifyData->Action == FILE_ACTION_MODIFIED || notifyData->Action == FILE_ACTION_RENAMED_NEW_NAME) - { - if (wcscmp(notifyData->FileName, DLLWatch) == 0) - { - DevData.FileWatcher.Change = true; - printf("detected dll change!\n"); - } - } - - if (notifyData->NextEntryOffset == 0) break; - offset += notifyData->NextEntryOffset; - } - } + FileChangeCheck(DevData.DevDir, FileChangeType::DLL, DLLWatch); + FileChangeCheck(DevData.ShaderDir, FileChangeType::Shader); + FileChangeCheck(DevData.CompiledShaderDir, FileChangeType::CompiledShader); } printf("File watcher thread ended!\n"); return 0; @@ -151,6 +191,17 @@ bool ReloadDLL() return true; } +HANDLE LoadDirHandle(const char* name) +{ + return CreateFileA(name, + FILE_LIST_DIRECTORY, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, + NULL); +} + int main() { char PathBuf[512]{ 0 }; @@ -166,13 +217,11 @@ int main() return 1; } - DevData.hDevDir = CreateFile(".", - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, - NULL); + Shared.Dev.ShaderChangeQueue = &DevData.FileWatcher.ShaderQueue; + DevData.DevDir = LoadDirHandle("."); + DevData.ShaderDir = LoadDirHandle("../game/shaders"); + DevData.CompiledShaderDir = LoadDirHandle("../game/compiled-shaders"); + DWORD fileWatcherThreadId = 0; CreateThread(NULL, 0, FileWatcherThread, NULL, 0, &fileWatcherThreadId); @@ -186,9 +235,11 @@ int main() { isRunning = false; } - if (DevData.FileWatcher.Change) + FileChangeNotification* DLLChange = nullptr; + if (DevData.FileWatcher.DLLQueue.pop()) { - DevData.FileWatcher.Change = false; + // Empty queue to avoid multiple reloads + while (DevData.FileWatcher.DLLQueue.pop()) {} ShutdownFunc(); ReloadDLL(); StartupFunc(Shared); diff --git a/src/game/rendering/Rendering.cpp b/src/game/rendering/Rendering.cpp index af09ec0..bc15488 100644 --- a/src/game/rendering/Rendering.cpp +++ b/src/game/rendering/Rendering.cpp @@ -152,6 +152,18 @@ namespace Game void GameRendering::Update() { SharedData& shared = GetShared(); + + FileChangeNotification* shaderChange = nullptr; + while ((shaderChange = shared.Dev.ShaderChangeQueue->pop())) + { + bgfx::destroy(Shader); + VertexBuffer = bgfx::createVertexBuffer(bgfx::makeRef(cubeVertices, sizeof(cubeVertices)), VertLayout); + IndexBuffer = bgfx::createIndexBuffer(bgfx::makeRef(cubeTriList, sizeof(cubeTriList))); + bgfx::ShaderHandle vertexShader = loadShader("vert"); + bgfx::ShaderHandle fragmentShader = loadShader("frag"); + Shader = bgfx::createProgram(vertexShader, fragmentShader, true); + } + int64_t tickDelta = bx::getHPCounter() - GetInstance().StartTime; double time = tickDelta / double(bx::getHPFrequency()); @@ -211,7 +223,7 @@ namespace Game } } - bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1f", time); + bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.2f", time); bgfx::dbgTextPrintf(1, 2, 0x0f, "Frame: %u", GetInstance().FrameCounter); bgfx::frame();