conversion to c by gemini 4 argon
This commit is contained in:
1 parent
b70e2d21d2
commit
f9356f9ba7
369 files changed
+18074
-107634
No files matched your search
@@ -0,0 +1,348 @@
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <Core/Common/String.h>
|
||||
#include <Core/HAL/Display/Display.h>
|
||||
#include <Core/HAL/Event/SystemEvent.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/HotReload/HotReload.h>
|
||||
#include <Core/JulietInit.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Main.h>
|
||||
#include <Core/Math/Matrix.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Core/Memory/Utils.h>
|
||||
|
||||
#include <Engine/Debug/MemoryDebugger.h>
|
||||
#include <Engine/Engine.h>
|
||||
#include <Graphics/Camera.h>
|
||||
#include <Graphics/DebugDisplay.h>
|
||||
#include <Graphics/Graphics.h>
|
||||
#include <Graphics/GraphicsConfig.h>
|
||||
#include <Graphics/GraphicsPipeline.h>
|
||||
#include <Graphics/Mesh.h>
|
||||
#include <Graphics/MeshRenderer.h>
|
||||
#include <Graphics/RenderPass.h>
|
||||
#include <Graphics/SkyboxRenderer.h>
|
||||
#include <Graphics/VertexData.h>
|
||||
|
||||
#ifdef JULIET_ENABLE_IMGUI
|
||||
#include <dcimgui.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
global bool8 g_show_memory_debugger = false;
|
||||
|
||||
typedef void (*GameShutdown_t)(void);
|
||||
typedef void (*GameUpdate_t)(GameData* params, float deltaTime);
|
||||
|
||||
typedef struct GameFunctionTableStruct GameFunctionTableStruct;
|
||||
struct GameFunctionTableStruct
|
||||
{
|
||||
GameShutdown_t Shutdown;
|
||||
GameUpdate_t Update;
|
||||
};
|
||||
|
||||
global GameFunctionTableStruct g_game = { 0 };
|
||||
global GameData g_game_data = { 0 };
|
||||
global const char* g_game_function_names[] = { "GameShutdown", "GameUpdate" };
|
||||
|
||||
typedef struct JulietAppState JulietAppState;
|
||||
struct JulietAppState
|
||||
{
|
||||
Window* MainWindow;
|
||||
GraphicsDevice* GraphicsDevice;
|
||||
GraphicsPipeline* GraphicsPipeline;
|
||||
Texture* DepthBuffer;
|
||||
HotReloadCode GameCode;
|
||||
bool8 Running;
|
||||
float CameraTime;
|
||||
int AutoCloseFrameCount;
|
||||
};
|
||||
|
||||
global JulietAppState g_app = {
|
||||
.MainWindow = NULL,
|
||||
.GraphicsDevice = NULL,
|
||||
.GraphicsPipeline = NULL,
|
||||
.DepthBuffer = NULL,
|
||||
.Running = false,
|
||||
.CameraTime = 0.0f,
|
||||
.AutoCloseFrameCount = -1
|
||||
};
|
||||
|
||||
internal void App_Init(Arena* platformArena)
|
||||
{
|
||||
Assert(platformArena != NULL);
|
||||
|
||||
Log(LogLevel_Message, LogCategory_Tool, "Initializing Juliet Application...");
|
||||
Log(LogLevel_Message, LogCategory_Tool, "%s", CStr(GetBasePath().Directories));
|
||||
|
||||
GraphicsConfig config = { 0 };
|
||||
#if JULIET_DEBUG
|
||||
config.EnableDebug = true;
|
||||
#endif
|
||||
|
||||
g_app.GraphicsDevice = CreateGraphicsDevice(config);
|
||||
|
||||
g_app.MainWindow = CreatePlatformWindow("Juliet", 1920, 1080, 0);
|
||||
|
||||
g_app.Running = (g_app.MainWindow != NULL && g_app.GraphicsDevice != NULL);
|
||||
|
||||
if (g_app.Running)
|
||||
{
|
||||
AttachToWindow(g_app.GraphicsDevice, g_app.MainWindow);
|
||||
{
|
||||
// Create Depth Buffer
|
||||
TextureCreateInfo depthCI = { 0 };
|
||||
depthCI.Type = TextureType_2D;
|
||||
depthCI.Width = 1920;
|
||||
depthCI.Height = 1080;
|
||||
depthCI.Format = TextureFormat_D32_FLOAT;
|
||||
depthCI.Flags = TextureUsageFlag_DepthStencilTarget;
|
||||
depthCI.LayerCount = 1;
|
||||
depthCI.MipLevelCount = 1;
|
||||
depthCI.SampleCount = TextureSampleCount_One;
|
||||
g_app.DepthBuffer = CreateTexture(g_app.GraphicsDevice, &depthCI);
|
||||
if (g_app.DepthBuffer == NULL)
|
||||
{
|
||||
LogError(LogCategory_Game, "Failed to create depth buffer!");
|
||||
g_app.Running = false;
|
||||
}
|
||||
}
|
||||
|
||||
g_app.GameCode.Functions = (void**)&g_game;
|
||||
g_app.GameCode.FunctionCount = ArraySize(g_game_function_names);
|
||||
g_app.GameCode.FunctionNames = g_game_function_names;
|
||||
InitHotReloadCode(platformArena, &g_app.GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"),
|
||||
ConstString("lock.tmp"));
|
||||
g_app.Running = g_app.GameCode.IsValid;
|
||||
}
|
||||
}
|
||||
|
||||
internal void App_Shutdown(void)
|
||||
{
|
||||
Log(LogLevel_Message, LogCategory_Tool, "Shutting down Juliet Application...");
|
||||
|
||||
if (g_app.GameCode.IsValid)
|
||||
{
|
||||
g_game.Shutdown();
|
||||
ShutdownHotReloadCode(&g_app.GameCode);
|
||||
}
|
||||
|
||||
if (g_app.GraphicsPipeline != NULL)
|
||||
{
|
||||
DestroyGraphicsPipeline(g_app.GraphicsDevice, g_app.GraphicsPipeline);
|
||||
}
|
||||
|
||||
if (g_app.DepthBuffer != NULL)
|
||||
{
|
||||
DestroyTexture(g_app.GraphicsDevice, g_app.DepthBuffer);
|
||||
}
|
||||
|
||||
if (g_app.MainWindow != NULL && g_app.GraphicsDevice != NULL)
|
||||
{
|
||||
DetachFromWindow(g_app.GraphicsDevice, g_app.MainWindow);
|
||||
}
|
||||
|
||||
if (g_app.MainWindow != NULL)
|
||||
{
|
||||
DestroyPlatformWindow(g_app.MainWindow);
|
||||
}
|
||||
|
||||
if (g_app.GraphicsDevice != NULL)
|
||||
{
|
||||
DestroyGraphicsDevice(g_app.GraphicsDevice);
|
||||
}
|
||||
|
||||
Log(LogLevel_Message, LogCategory_Tool, "Juliet App shutdown Completed");
|
||||
}
|
||||
|
||||
internal void App_Update(float deltaTime)
|
||||
{
|
||||
g_app.CameraTime += deltaTime;
|
||||
|
||||
static float fpsTimer = 0.0f;
|
||||
static int fpsFrames = 0;
|
||||
fpsTimer += deltaTime;
|
||||
fpsFrames++;
|
||||
if (fpsTimer >= 0.5f)
|
||||
{
|
||||
float fps = (float)fpsFrames / fpsTimer;
|
||||
float ms = (fpsTimer / (float)fpsFrames) * 1000.0f;
|
||||
char title[64];
|
||||
snprintf(title, sizeof(title), "Juliet | %.1f FPS | %.2f ms", (double)fps, (double)ms);
|
||||
SetWindowTitle(g_app.MainWindow, WrapString(title));
|
||||
fpsTimer = 0.0f;
|
||||
fpsFrames = 0;
|
||||
}
|
||||
|
||||
bool8 reloadShaders = false;
|
||||
static bool8 reloadShadersDebounce = false;
|
||||
|
||||
SystemEvent evt = { 0 };
|
||||
while (GetEvent(&evt))
|
||||
{
|
||||
if (evt.Type == EventType_Window_Close_Request)
|
||||
{
|
||||
if (evt.Data.Window.AssociatedWindowID == GetWindowID(g_app.MainWindow))
|
||||
{
|
||||
g_app.Running = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Shader hot reload using keyboard.
|
||||
if (!reloadShadersDebounce && ((GetKeyModState() & KeyMod_Alt) != KeyMod_None) && IsKeyDown(ScanCode_R))
|
||||
{
|
||||
reloadShaders = true;
|
||||
reloadShadersDebounce = true;
|
||||
}
|
||||
|
||||
if (reloadShadersDebounce && !IsKeyDown(ScanCode_R))
|
||||
{
|
||||
reloadShadersDebounce = false;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 origin = { 0.0f, 0.0f, 0.0f };
|
||||
Vector3 xAxis = { 1.0f, 0.0f, 0.0f };
|
||||
Vector3 yAxis = { 0.0f, 1.0f, 0.0f };
|
||||
Vector3 zAxis = { 0.0f, 0.0f, 1.0f };
|
||||
FColor redCol = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||
FColor greenCol = { 0.0f, 1.0f, 0.0f, 1.0f };
|
||||
FColor blueCol = { 0.0f, 0.0f, 1.0f, 1.0f };
|
||||
FColor yelCol = { 1.0f, 1.0f, 0.0f, 1.0f };
|
||||
|
||||
DebugDisplay_DrawLine(origin, xAxis, redCol, false);
|
||||
DebugDisplay_DrawLine(origin, yAxis, greenCol, true);
|
||||
DebugDisplay_DrawLine(origin, zAxis, blueCol, true);
|
||||
DebugDisplay_DrawSphere(origin, 0.5f, yelCol, true);
|
||||
|
||||
g_game.Update(&g_game_data, deltaTime);
|
||||
|
||||
if (ShouldReloadCode(&g_app.GameCode))
|
||||
{
|
||||
ReloadCode(&g_app.GameCode);
|
||||
}
|
||||
|
||||
if (reloadShaders)
|
||||
{
|
||||
WaitUntilGPUIsIdle(g_app.GraphicsDevice);
|
||||
|
||||
#if ALLOW_SHADER_HOT_RELOAD
|
||||
ReloadMeshRendererShaders();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Memory debugger toggle
|
||||
static bool8 toggleDebounce = false;
|
||||
if (IsKeyDown(ScanCode_Home))
|
||||
{
|
||||
if (!toggleDebounce)
|
||||
{
|
||||
g_show_memory_debugger = !g_show_memory_debugger;
|
||||
toggleDebounce = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
toggleDebounce = false;
|
||||
}
|
||||
|
||||
// Auto-close logic
|
||||
if (g_app.AutoCloseFrameCount > 0)
|
||||
{
|
||||
g_app.AutoCloseFrameCount--;
|
||||
if (g_app.AutoCloseFrameCount == 0)
|
||||
{
|
||||
Log(LogLevel_Message, LogCategory_Tool, "Auto-closing application as requested.");
|
||||
g_app.Running = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_show_memory_debugger)
|
||||
{
|
||||
#if JULIET_DEBUG
|
||||
Debug_DebugDrawMemoryArena();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal ColorTargetInfo App_GetColorTargetInfo(Texture* swapchainTexture)
|
||||
{
|
||||
ColorTargetInfo info = { 0 };
|
||||
info.TargetTexture = swapchainTexture;
|
||||
info.ClearColor = (FColor){ .R = 0.0f, .G = 0.0f, .B = 0.0f, .A = 1.0f };
|
||||
info.LoadOperation = LoadOperation_Clear;
|
||||
info.StoreOperation = StoreOperation_Store;
|
||||
return info;
|
||||
}
|
||||
|
||||
internal DepthStencilTargetInfo* App_GetDepthTargetInfo(void)
|
||||
{
|
||||
static DepthStencilTargetInfo info = { 0 };
|
||||
info.TargetTexture = g_app.DepthBuffer;
|
||||
info.ClearDepth = 1.0f;
|
||||
info.LoadOperation = LoadOperation_Clear;
|
||||
info.StoreOperation = StoreOperation_Store;
|
||||
return &info;
|
||||
}
|
||||
|
||||
internal bool8 App_IsRunning(void)
|
||||
{
|
||||
return g_app.Running;
|
||||
}
|
||||
|
||||
internal Window* App_GetPlatformWindow(void)
|
||||
{
|
||||
return g_app.MainWindow;
|
||||
}
|
||||
|
||||
internal GraphicsDevice* App_GetGraphicsDevice(void)
|
||||
{
|
||||
return g_app.GraphicsDevice;
|
||||
}
|
||||
|
||||
int JulietMain(int argc, wchar_t** argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (wcscmp(argv[i], L"-autoclose") == 0 && (i + 1 < argc))
|
||||
{
|
||||
int frames = _wtoi(argv[i + 1]);
|
||||
g_app.AutoCloseFrameCount = frames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationCallbacks appCallbacks = {
|
||||
.Init = App_Init,
|
||||
.Shutdown = App_Shutdown,
|
||||
.Update = App_Update,
|
||||
.IsRunning = App_IsRunning,
|
||||
.GetPlatformWindow = App_GetPlatformWindow,
|
||||
.GetGraphicsDevice = App_GetGraphicsDevice,
|
||||
.GetColorTargetInfo = App_GetColorTargetInfo,
|
||||
.GetDepthTargetInfo = App_GetDepthTargetInfo,
|
||||
};
|
||||
|
||||
StartApplication(appCallbacks, JulietInit_Flags_Display);
|
||||
|
||||
// Pause here to not close the console window immediately on stop
|
||||
// Only pause if not in auto-close mode
|
||||
if (g_app.AutoCloseFrameCount == -1 && !Debug_IsDebuggerPresent())
|
||||
{
|
||||
system("PAUSE");
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,655 +0,0 @@
|
||||
#include "main.h"
|
||||
|
||||
#ifdef global
|
||||
#undef global
|
||||
#endif
|
||||
|
||||
#define global static
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <Core/Application/ApplicationManager.h>
|
||||
#include <Core/Common/EnumUtils.h>
|
||||
#include <Core/Common/String.h>
|
||||
#include <Core/HAL/Display/Display.h>
|
||||
#include <Core/HAL/Event/SystemEvent.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/JulietInit.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Main.h>
|
||||
#include <Core/Math/Matrix.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Core/Memory/Utils.h>
|
||||
|
||||
#include <Engine/Debug/MemoryDebugger.h>
|
||||
#include <Graphics/Camera.h>
|
||||
#include <Graphics/DebugDisplay.h>
|
||||
#include <Graphics/Graphics.h>
|
||||
#include <Graphics/GraphicsConfig.h>
|
||||
#include <Graphics/GraphicsPipeline.h>
|
||||
#include <Graphics/Mesh.h>
|
||||
#include <Graphics/MeshRenderer.h>
|
||||
#include <Graphics/RenderPass.h>
|
||||
#include <Graphics/SkyboxRenderer.h>
|
||||
#include <Graphics/VertexData.h>
|
||||
|
||||
#ifdef JULIET_ENABLE_IMGUI
|
||||
#include <imgui.h>
|
||||
#endif
|
||||
|
||||
static bool ShowMemoryDebugger = false;
|
||||
|
||||
#if 0
|
||||
static bool animateCubes = true;
|
||||
static bool animateLights = true;
|
||||
static bool animateCamera = true;
|
||||
|
||||
static bool freeCameraMode = false;
|
||||
static float camYaw = 0.0f;
|
||||
static float camPitch = 0.0f;
|
||||
static Vector3 camPos = { 25.0f, 0.0f, 12.5f };
|
||||
|
||||
static float animateCubesTime = 0.0f;
|
||||
static float animateLightsTime = 0.0f;
|
||||
static float animateCameraTime = 0.0f;
|
||||
|
||||
static float redLightRadius = 10.0f;
|
||||
static float redLightIntensity = 5.0f;
|
||||
static float redLightColor[3] = { 1.0f, 0.2f, 0.2f };
|
||||
static bool redLightFollowsCamera = false;
|
||||
|
||||
static bool enableGlobalLight = true;
|
||||
static float globalLightDir[3] = { 0.5f, -1.0f, -0.5f };
|
||||
static float globalLightColor[3] = { 1.0f, 0.95f, 0.8f };
|
||||
static float globalAmbientIntensity = 0.2f;
|
||||
|
||||
static float blueLightRadius = 15.0f;
|
||||
static float blueLightIntensity = 8.0f;
|
||||
static float blueLightColor[3] = { 0.2f, 0.2f, 1.0f };
|
||||
#endif
|
||||
|
||||
// TODO : Replace with message box from framework + call main and not winmain + subsystem
|
||||
// TODO : Think how to do the draw pipeline.
|
||||
// Ex: Expose a Draw method ?
|
||||
// Store a graphics context ?
|
||||
// For now. Put everything in Update down below.
|
||||
// Should split update from draw, update should have a != timestep than graphics (60fps or more)
|
||||
|
||||
// TODO : Remove main.h. Useless
|
||||
// May be remove that Application class, useless too.
|
||||
|
||||
namespace
|
||||
{
|
||||
using GameShutdown_t = void (*)(void);
|
||||
using GameUpdate_t = void (*)(GameData* params, float deltaTime);
|
||||
struct GameFunctionTable
|
||||
{
|
||||
GameShutdown_t Shutdown = nullptr;
|
||||
GameUpdate_t Update = nullptr;
|
||||
} Game;
|
||||
GameData Data;
|
||||
|
||||
const char* GameFunctionTable[] = { "GameShutdown", "GameUpdate" };
|
||||
|
||||
#if 0
|
||||
LightID RedLightID = 0;
|
||||
LightID BlueLightID = 0;
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
void JulietApplication::Init(NonNullPtr<Arena> platformArena)
|
||||
{
|
||||
Log(LogLevel::Message, LogCategory::Tool, "Initializing Juliet Application...");
|
||||
Log(LogLevel::Message, LogCategory::Tool, "%s", CStr(GetBasePath().Directories));
|
||||
|
||||
GraphicsConfig config;
|
||||
#if JULIET_DEBUG
|
||||
config.EnableDebug = true;
|
||||
#endif
|
||||
|
||||
GraphicsDevice = CreateGraphicsDevice(config);
|
||||
|
||||
MainWindow = CreatePlatformWindow("Juliet", 1920, 1080);
|
||||
|
||||
Running = MainWindow != nullptr && GraphicsDevice != nullptr;
|
||||
|
||||
if (Running)
|
||||
{
|
||||
AttachToWindow(GraphicsDevice, MainWindow);
|
||||
{
|
||||
// Create Depth Buffer
|
||||
TextureCreateInfo depthCI = {};
|
||||
depthCI.Type = TextureType::Texture_2D;
|
||||
depthCI.Width = 1920;
|
||||
depthCI.Height = 1080;
|
||||
depthCI.Format = TextureFormat::D32_FLOAT;
|
||||
depthCI.Flags = TextureUsageFlag::DepthStencilTarget;
|
||||
depthCI.LayerCount = 1;
|
||||
depthCI.MipLevelCount = 1;
|
||||
depthCI.SampleCount = TextureSampleCount::One;
|
||||
DepthBuffer = CreateTexture(GraphicsDevice, depthCI);
|
||||
if (DepthBuffer == nullptr)
|
||||
{
|
||||
LogError(LogCategory::Game, "Failed to create depth buffer!");
|
||||
Running = false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
constexpr int kGridSize = 10;
|
||||
constexpr float kSpacing = 2.5f;
|
||||
constexpr float kOffset = (kGridSize - 1) * kSpacing * 0.5f;
|
||||
|
||||
for (int row = 0; row < kGridSize; ++row)
|
||||
{
|
||||
for (int col = 0; col < kGridSize; ++col)
|
||||
{
|
||||
MeshAssetID cubeAsset = GetCubePrimitiveMeshAssetID();
|
||||
float x = static_cast<float>(col) * kSpacing - kOffset;
|
||||
float y = static_cast<float>(row) * kSpacing - kOffset;
|
||||
|
||||
float seed = static_cast<float>(row * kGridSize + col);
|
||||
Matrix rotation = MatrixRotation(seed * 0.73f, seed * 1.17f, seed * 0.53f);
|
||||
CreateMeshInstance(cubeAsset, 0, MatrixTranslation(x, y, 0.0f) * rotation);
|
||||
}
|
||||
}
|
||||
|
||||
// Start with some default test lights
|
||||
PointLight redLight = {};
|
||||
redLight.Position = { 5.0f, 5.0f, 2.0f };
|
||||
redLight.Radius = redLightRadius;
|
||||
redLight.Color = { redLightColor[0], redLightColor[1], redLightColor[2] };
|
||||
redLight.Intensity = redLightIntensity;
|
||||
RedLightID = AddPointLight(redLight);
|
||||
|
||||
PointLight blueLight = {};
|
||||
blueLight.Position = { -5.0f, 0.0f, 2.0f };
|
||||
blueLight.Radius = blueLightRadius;
|
||||
blueLight.Color = { blueLightColor[0], blueLightColor[1], blueLightColor[2] };
|
||||
blueLight.Intensity = blueLightIntensity;
|
||||
BlueLightID = AddPointLight(blueLight);
|
||||
#endif
|
||||
}
|
||||
|
||||
GameCode.Functions = reinterpret_cast<void**>(&Game);
|
||||
GameCode.FunctionCount = ArraySize(GameFunctionTable);
|
||||
GameCode.FunctionNames = GameFunctionTable;
|
||||
InitHotReloadCode(platformArena, GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
|
||||
Running = GameCode.IsValid;
|
||||
}
|
||||
}
|
||||
|
||||
void JulietApplication::Shutdown()
|
||||
{
|
||||
Log(LogLevel::Message, LogCategory::Tool, "Shutting down Juliet Application...");
|
||||
|
||||
if (GameCode.IsValid)
|
||||
{
|
||||
Game.Shutdown();
|
||||
ShutdownHotReloadCode(GameCode);
|
||||
}
|
||||
|
||||
if (GraphicsPipeline)
|
||||
{
|
||||
DestroyGraphicsPipeline(GraphicsDevice, GraphicsPipeline);
|
||||
}
|
||||
|
||||
if (DepthBuffer)
|
||||
{
|
||||
DestroyTexture(GraphicsDevice, DepthBuffer);
|
||||
}
|
||||
|
||||
if (MainWindow && GraphicsDevice)
|
||||
{
|
||||
DetachFromWindow(GraphicsDevice, MainWindow);
|
||||
}
|
||||
|
||||
if (MainWindow)
|
||||
{
|
||||
DestroyPlatformWindow(MainWindow);
|
||||
}
|
||||
|
||||
if (GraphicsDevice)
|
||||
{
|
||||
DestroyGraphicsDevice(GraphicsDevice);
|
||||
}
|
||||
|
||||
Log(LogLevel::Message, LogCategory::Tool, "Juliet App shutdown Completed");
|
||||
}
|
||||
|
||||
void JulietApplication::Update(float deltaTime)
|
||||
{
|
||||
|
||||
CameraTime += deltaTime;
|
||||
|
||||
static float fpsTimer = 0.0f;
|
||||
static int fpsFrames = 0;
|
||||
fpsTimer += deltaTime;
|
||||
fpsFrames++;
|
||||
if (fpsTimer >= 0.5f)
|
||||
{
|
||||
float fps = static_cast<float>(fpsFrames) / fpsTimer;
|
||||
float ms = (fpsTimer / static_cast<float>(fpsFrames)) * 1000.0f;
|
||||
char title[64];
|
||||
snprintf(title, sizeof(title), "Juliet | %.1f FPS | %.2f ms", static_cast<double>(fps), static_cast<double>(ms));
|
||||
SetWindowTitle(MainWindow, WrapString(title));
|
||||
fpsTimer = 0.0f;
|
||||
fpsFrames = 0;
|
||||
}
|
||||
|
||||
bool reloadShaders = false;
|
||||
static bool reloadShadersDebounce = false;
|
||||
|
||||
#if 0
|
||||
static bool f1Debounce = false;
|
||||
#endif
|
||||
|
||||
SystemEvent evt;
|
||||
while (GetEvent(evt))
|
||||
{
|
||||
if (evt.Type == EventType::Window_Close_Request)
|
||||
{
|
||||
if (evt.Data.Window.AssociatedWindowID == GetWindowID(MainWindow))
|
||||
{
|
||||
Running = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Shader hot reload using keyboard.
|
||||
if (!reloadShadersDebounce && ((GetKeyModState() & KeyMod::Alt) != KeyMod::None) && IsKeyDown(ScanCode::R))
|
||||
{
|
||||
reloadShaders = true;
|
||||
reloadShadersDebounce = true;
|
||||
}
|
||||
|
||||
if (reloadShadersDebounce && !IsKeyDown(ScanCode::R))
|
||||
{
|
||||
reloadShadersDebounce = false;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool firstFreeFrame = false;
|
||||
|
||||
if (IsKeyDown(ScanCode::F1))
|
||||
{
|
||||
if (!f1Debounce)
|
||||
{
|
||||
freeCameraMode = !freeCameraMode;
|
||||
if (freeCameraMode)
|
||||
{
|
||||
firstFreeFrame = true;
|
||||
}
|
||||
f1Debounce = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
f1Debounce = false;
|
||||
}
|
||||
|
||||
// Confine and hide the mouse for Free Camera mode
|
||||
if (freeCameraMode)
|
||||
{
|
||||
#ifdef JULIET_ENABLE_IMGUI
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_None);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
HWND hwnd = GetForegroundWindow();
|
||||
if (hwnd)
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
POINT ptCenterClient = { (rect.right - rect.left) / 2, (rect.bottom - rect.top) / 2 };
|
||||
|
||||
if (!firstFreeFrame)
|
||||
{
|
||||
POINT currentPos;
|
||||
GetCursorPos(¤tPos);
|
||||
ScreenToClient(hwnd, ¤tPos);
|
||||
|
||||
float deltaX = static_cast<float>(currentPos.x - ptCenterClient.x);
|
||||
float deltaY = static_cast<float>(currentPos.y - ptCenterClient.y);
|
||||
|
||||
float sensitivity = 0.005f;
|
||||
// Plus because the mouse is inverted inherently by windows to screen coordinate
|
||||
camYaw += deltaX * sensitivity;
|
||||
camPitch -= deltaY * sensitivity;
|
||||
|
||||
camPitch = std::min(camPitch, 1.5f);
|
||||
camPitch = std::max(camPitch, -1.5f);
|
||||
}
|
||||
firstFreeFrame = false;
|
||||
|
||||
POINT ptCenterScreen = ptCenterClient;
|
||||
ClientToScreen(hwnd, &ptCenterScreen);
|
||||
SetCursorPos(ptCenterScreen.x, ptCenterScreen.y);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (freeCameraMode)
|
||||
{
|
||||
float speed = 10.0f * deltaTime;
|
||||
if ((GetKeyModState() & KeyMod::Shift) != KeyMod::None)
|
||||
{
|
||||
speed *= 3.0f;
|
||||
}
|
||||
|
||||
Vector3 forward = { cosf(camYaw) * cosf(camPitch), sinf(camYaw) * cosf(camPitch), sinf(camPitch) };
|
||||
Vector3 right = { cosf(camYaw + 1.5708f), sinf(camYaw + 1.5708f), 0.0f };
|
||||
Vector3 up = { 0.0f, 0.0f, 1.0f };
|
||||
|
||||
if (IsKeyDown(ScanCode::W))
|
||||
{
|
||||
camPos = camPos + forward * speed;
|
||||
}
|
||||
if (IsKeyDown(ScanCode::S))
|
||||
{
|
||||
camPos = camPos - forward * speed;
|
||||
}
|
||||
if (IsKeyDown(ScanCode::D))
|
||||
{
|
||||
camPos = camPos + right * speed;
|
||||
}
|
||||
if (IsKeyDown(ScanCode::A))
|
||||
{
|
||||
camPos = camPos - right * speed;
|
||||
}
|
||||
if (IsKeyDown(ScanCode::E))
|
||||
{
|
||||
camPos = camPos + up * speed;
|
||||
}
|
||||
if (IsKeyDown(ScanCode::Q))
|
||||
{
|
||||
camPos = camPos - up * speed;
|
||||
}
|
||||
}
|
||||
|
||||
if (animateCubes)
|
||||
{
|
||||
animateCubesTime += deltaTime;
|
||||
}
|
||||
if (animateLights)
|
||||
{
|
||||
animateLightsTime += deltaTime;
|
||||
}
|
||||
if (animateCamera)
|
||||
{
|
||||
animateCameraTime += deltaTime;
|
||||
}
|
||||
|
||||
#ifdef JULIET_ENABLE_IMGUI
|
||||
ImGui::Begin("Debug Controls");
|
||||
ImGui::Checkbox("Animate Cubes", &animateCubes);
|
||||
ImGui::Checkbox("Animate Lights", &animateLights);
|
||||
ImGui::Checkbox("Animate Camera", &animateCamera);
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Global Light");
|
||||
ImGui::Checkbox("Enable Global Light", &enableGlobalLight);
|
||||
if (enableGlobalLight)
|
||||
{
|
||||
ImGui::SliderFloat3("Direction", globalLightDir, -1.0f, 1.0f);
|
||||
ImGui::ColorEdit3("Color", globalLightColor);
|
||||
ImGui::SliderFloat("Ambient Intensity", &globalAmbientIntensity, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Red Point Light");
|
||||
ImGui::ColorEdit3("Red Color", redLightColor);
|
||||
ImGui::SliderFloat("Red Radius", &redLightRadius, 1.0f, 50.0f);
|
||||
ImGui::SliderFloat("Red Intensity", &redLightIntensity, 0.0f, 50.0f);
|
||||
ImGui::Checkbox("Red Light Follows Camera", &redLightFollowsCamera);
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Blue Point Light");
|
||||
ImGui::ColorEdit3("Blue Color", blueLightColor);
|
||||
ImGui::SliderFloat("Blue Radius", &blueLightRadius, 1.0f, 50.0f);
|
||||
ImGui::SliderFloat("Blue Intensity", &blueLightIntensity, 0.0f, 50.0f);
|
||||
|
||||
ImGui::End();
|
||||
#endif
|
||||
|
||||
Vector3 redLightPos = { 5.0f, 5.0f, 2.0f };
|
||||
Vector3 blueLightPos = { -5.0f, 0.0f, 2.0f };
|
||||
|
||||
if (animateLights || animateLightsTime > 0.0f)
|
||||
{
|
||||
redLightPos = { cosf(animateLightsTime * 2.0f) * 5.0f, sinf(animateLightsTime * 2.0f) * 5.0f, 2.0f };
|
||||
blueLightPos = { -5.0f, cosf(animateLightsTime) * 3.0f, 2.0f };
|
||||
}
|
||||
|
||||
if (redLightFollowsCamera)
|
||||
{
|
||||
Camera cam = GetDebugCamera();
|
||||
redLightPos = cam.Position;
|
||||
}
|
||||
|
||||
SetPointLightPosition(RedLightID, redLightPos);
|
||||
SetPointLightPosition(BlueLightID, blueLightPos);
|
||||
|
||||
SetPointLightColor(RedLightID, { redLightColor[0], redLightColor[1], redLightColor[2] });
|
||||
SetPointLightRadius(RedLightID, redLightRadius);
|
||||
SetPointLightIntensity(RedLightID, redLightIntensity);
|
||||
|
||||
SetPointLightColor(BlueLightID, { blueLightColor[0], blueLightColor[1], blueLightColor[2] });
|
||||
SetPointLightRadius(BlueLightID, blueLightRadius);
|
||||
SetPointLightIntensity(BlueLightID, blueLightIntensity);
|
||||
|
||||
// Animate the 100 cubes (10x10 grid)
|
||||
constexpr int kGridSize = 10;
|
||||
constexpr float kSpacing = 2.5f;
|
||||
constexpr float kOffset = (kGridSize - 1) * kSpacing * 0.5f;
|
||||
|
||||
for (int row = 0; row < kGridSize; ++row)
|
||||
{
|
||||
for (int col = 0; col < kGridSize; ++col)
|
||||
{
|
||||
MeshID cube = static_cast<MeshID>(row * kGridSize + col); // Assuming they were added first
|
||||
float x = static_cast<float>(col) * kSpacing - kOffset;
|
||||
float y = static_cast<float>(row) * kSpacing - kOffset;
|
||||
|
||||
float seed = static_cast<float>(cube);
|
||||
float timeZ = animateCubesTime * 2.0f + seed * 0.5f;
|
||||
float z = 0.0f;
|
||||
|
||||
float scaleF = 1.0f;
|
||||
Matrix rotation = MatrixIdentity();
|
||||
|
||||
if (animateCubes || animateCubesTime > 0.0f)
|
||||
{
|
||||
z = sinf(timeZ) * 1.5f; // Oscillate up and down
|
||||
scaleF = 1.0f + sinf(animateCubesTime * 1.5f + seed) * 0.3f; // Pulse scale
|
||||
rotation = MatrixRotation(animateCubesTime * 1.2f + seed * 0.73f, animateCubesTime * 0.8f + seed * 1.17f,
|
||||
animateCubesTime * 0.5f + seed * 0.53f);
|
||||
}
|
||||
Matrix scale = MatrixScale(scaleF, scaleF, scaleF);
|
||||
|
||||
SetMeshTransform(cube, MatrixTranslation(x, y, z) * rotation * scale);
|
||||
}
|
||||
}
|
||||
DebugDisplay_DrawSphere(blueLightPos, 0.5f, { 0.0f, 0.0f, 1.0f, 1.0f }, true);
|
||||
DebugDisplay_DrawSphere(redLightPos, 0.5f, { 1.0f, 0.0f, 0.0f, 1.0f }, true);
|
||||
#endif
|
||||
|
||||
DebugDisplay_DrawLine({ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }, false);
|
||||
DebugDisplay_DrawLine({ 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f }, true);
|
||||
DebugDisplay_DrawLine({ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, true);
|
||||
DebugDisplay_DrawSphere({ 0.0f, 0.0f, 0.0f }, 0.5f, { 1.0f, 1.0f, 0.0f, 1.0f }, true);
|
||||
|
||||
Game.Update(&Data, deltaTime);
|
||||
|
||||
if (ShouldReloadCode(GameCode))
|
||||
{
|
||||
ReloadCode(GameCode);
|
||||
}
|
||||
|
||||
if (reloadShaders)
|
||||
{
|
||||
WaitUntilGPUIsIdle(GraphicsDevice);
|
||||
|
||||
#if ALLOW_SHADER_HOT_RELOAD
|
||||
ReloadMeshRendererShaders();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Memory debugger toggle
|
||||
static bool toggleDebounce = false;
|
||||
if (IsKeyDown(ScanCode::Home))
|
||||
{
|
||||
if (!toggleDebounce)
|
||||
{
|
||||
ShowMemoryDebugger = !ShowMemoryDebugger;
|
||||
toggleDebounce = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
toggleDebounce = false;
|
||||
}
|
||||
|
||||
// Auto-close logic
|
||||
if (AutoCloseFrameCount > 0)
|
||||
{
|
||||
AutoCloseFrameCount--;
|
||||
if (AutoCloseFrameCount == 0)
|
||||
{
|
||||
Log(LogLevel::Message, LogCategory::Tool, "Auto-closing application as requested.");
|
||||
Running = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowMemoryDebugger)
|
||||
{
|
||||
#if JULIET_DEBUG
|
||||
Debug::DebugDrawMemoryArena();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ColorTargetInfo JulietApplication::GetColorTargetInfo(Texture* swapchainTexture)
|
||||
{
|
||||
ColorTargetInfo info = {};
|
||||
info.TargetTexture = swapchainTexture;
|
||||
info.ClearColor = { .R = 0.0f, .G = 0.0f, .B = 0.0f, .A = 1.0f };
|
||||
info.LoadOperation = LoadOperation::Clear;
|
||||
info.StoreOperation = StoreOperation::Store;
|
||||
return info;
|
||||
}
|
||||
|
||||
DepthStencilTargetInfo* JulietApplication::GetDepthTargetInfo()
|
||||
{
|
||||
static DepthStencilTargetInfo info = {};
|
||||
info.TargetTexture = DepthBuffer;
|
||||
info.ClearDepth = 1.0f;
|
||||
info.LoadOperation = LoadOperation::Clear;
|
||||
info.StoreOperation = StoreOperation::Store;
|
||||
return &info;
|
||||
}
|
||||
|
||||
#if 0
|
||||
Camera JulietApplication::GetDebugCamera()
|
||||
{
|
||||
if (freeCameraMode)
|
||||
{
|
||||
Camera cam = {};
|
||||
cam.Position = camPos;
|
||||
cam.Target = camPos + Vector3{ cosf(camYaw) * cosf(camPitch), sinf(camYaw) * cosf(camPitch), sinf(camPitch) };
|
||||
cam.Up = { 0.0f, 0.0f, 1.0f };
|
||||
cam.FOV = 1.047f;
|
||||
cam.AspectRatio = 1200.0f / 800.0f;
|
||||
cam.NearPlane = 0.1f;
|
||||
cam.FarPlane = 1000.0f;
|
||||
return cam;
|
||||
}
|
||||
|
||||
// --- Adjusted for 1-Meter Scale ---
|
||||
float baseRadius = 25.0f; // Increased to see 10x10 cube grid
|
||||
|
||||
float radius = baseRadius;
|
||||
|
||||
if (animateCamera || animateCameraTime > 0.0f)
|
||||
{
|
||||
float orbitSpeed = 0.5f;
|
||||
float currentOrbitTime = animateCameraTime * orbitSpeed;
|
||||
|
||||
float zoomAmplitude = 15.0f;
|
||||
float zoomSpeed = 0.5f;
|
||||
radius = baseRadius + (sinf(animateCameraTime * zoomSpeed) * zoomAmplitude);
|
||||
|
||||
float zHeight = radius * 0.5f; // Keep a nice downward viewing angle
|
||||
|
||||
Camera cam = {};
|
||||
cam.Position = { cosf(currentOrbitTime) * radius, sinf(currentOrbitTime) * radius, zHeight };
|
||||
cam.Target = { 0.0f, 0.0f, 0.0f };
|
||||
cam.Up = { 0.0f, 0.0f, 1.0f };
|
||||
cam.FOV = 1.047f;
|
||||
cam.AspectRatio = 1200.0f / 800.0f;
|
||||
cam.NearPlane = 0.1f;
|
||||
cam.FarPlane = 1000.0f;
|
||||
|
||||
return cam;
|
||||
}
|
||||
|
||||
float zHeight = radius * 0.5f; // Keep a nice downward viewing angle
|
||||
|
||||
Camera cam = {};
|
||||
cam.Position = { radius, 0.0f, zHeight };
|
||||
cam.Target = { 0.0f, 0.0f, 0.0f };
|
||||
cam.Up = { 0.0f, 0.0f, 1.0f };
|
||||
cam.FOV = 1.047f;
|
||||
cam.AspectRatio = 1200.0f / 800.0f;
|
||||
cam.NearPlane = 0.1f;
|
||||
cam.FarPlane = 1000.0f;
|
||||
|
||||
return cam;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool JulietApplication::IsRunning()
|
||||
{
|
||||
return Running;
|
||||
}
|
||||
namespace
|
||||
{
|
||||
JulietApplication Application;
|
||||
}
|
||||
|
||||
JulietApplication& GetApplication()
|
||||
{
|
||||
return Application;
|
||||
}
|
||||
|
||||
int JulietMain(int argc, wchar_t** argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (wcscmp(argv[i], L"-autoclose") == 0 && (i + 1 < argc))
|
||||
{
|
||||
int frames = _wtoi(argv[i + 1]);
|
||||
Application.SetAutoCloseFrameCount(frames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StartApplication(Application, JulietInit_Flags::Display);
|
||||
|
||||
// Pause here to not close the console window immediatly on stop
|
||||
// Only pause if not in auto-close mode
|
||||
if (Application.GetAutoCloseFrameCount() == -1 && !Debug::IsDebuggerPresent())
|
||||
{
|
||||
system("PAUSE");
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Application/IApplication.h>
|
||||
#include <Core/HAL/Display/Display.h>
|
||||
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||
#include <Core/HotReload/HotReload.h>
|
||||
#include <Graphics/GraphicsPipeline.h>
|
||||
|
||||
struct Mesh;
|
||||
struct GraphicsTransferBuffer;
|
||||
struct GraphicsBuffer;
|
||||
struct GraphicsDevice;
|
||||
struct Window;
|
||||
|
||||
class JulietApplication : public IApplication
|
||||
{
|
||||
protected:
|
||||
void Init(NonNullPtr<Arena> arena) override;
|
||||
void Shutdown() override;
|
||||
void Update(float deltaTime) override;
|
||||
bool IsRunning() override;
|
||||
|
||||
Window* GetPlatformWindow() override { return MainWindow; }
|
||||
GraphicsDevice* GetGraphicsDevice() override { return GraphicsDevice; }
|
||||
|
||||
// Render Lifecycle
|
||||
ColorTargetInfo GetColorTargetInfo(Texture* swapchainTexture) override;
|
||||
DepthStencilTargetInfo* GetDepthTargetInfo() override;
|
||||
|
||||
#if 0
|
||||
Camera GetDebugCamera() override;
|
||||
#endif
|
||||
|
||||
public:
|
||||
void SetAutoCloseFrameCount(int count) { AutoCloseFrameCount = count; }
|
||||
int GetAutoCloseFrameCount() const { return AutoCloseFrameCount; }
|
||||
|
||||
private:
|
||||
Window* MainWindow = {};
|
||||
GraphicsDevice* GraphicsDevice = {};
|
||||
HotReloadCode GameCode = {};
|
||||
GraphicsPipeline* GraphicsPipeline = {};
|
||||
Texture* DepthBuffer = {};
|
||||
|
||||
int AutoCloseFrameCount = -1;
|
||||
bool Running = false;
|
||||
float CameraTime = 0.0f;
|
||||
};
|
||||
|
||||
JulietApplication& GetApplication();
|
||||
Reference in new issue
Block a user