226 lines
6.9 KiB
C++
226 lines
6.9 KiB
C++
#include <main.h>
|
|
|
|
#include <Core/Application/ApplicationManager.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 <Graphics/Graphics.h>
|
|
#include <Graphics/GraphicsConfig.h>
|
|
#include <Graphics/RenderPass.h>
|
|
|
|
#include <Core/Common/String.h>
|
|
#include <Core/Memory/Utils.h>
|
|
#include <cstdlib>
|
|
#include <Graphics/GraphicsPipeline.h>
|
|
|
|
// 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.
|
|
|
|
using namespace Juliet;
|
|
|
|
namespace
|
|
{
|
|
using GameInit_t = void (*)(void);
|
|
using GameShutdown_t = void (*)(void);
|
|
using GameUpdate_t = void (*)(float deltaTime);
|
|
struct GameFunctionTable
|
|
{
|
|
GameInit_t Init = nullptr;
|
|
GameShutdown_t Shutdown = nullptr;
|
|
GameUpdate_t Update = nullptr;
|
|
} Game;
|
|
const char* GameFunctionTable[] = { "GameInit", "GameShutdown", "GameUpdate" };
|
|
} // namespace
|
|
|
|
void JulietApplication::Init()
|
|
{
|
|
Log(LogLevel::Message, LogCategory::Tool, "Initializing Juliet Application...");
|
|
|
|
Log(LogLevel::Message, LogCategory::Tool, "%s", CStr(GetBasePath()));
|
|
|
|
GraphicsConfig config;
|
|
GraphicsDevice = CreateGraphicsDevice(config);
|
|
|
|
MainWindow = CreatePlatformWindow("Juliet Editor", 1280, 720);
|
|
|
|
Running = MainWindow != nullptr && GraphicsDevice != nullptr;
|
|
|
|
if (Running)
|
|
{
|
|
AttachToWindow(GraphicsDevice, MainWindow);
|
|
|
|
{
|
|
// Create graphics pipeline
|
|
String entryPoint = WrapString("main");
|
|
ShaderCreateInfo shaderCI = {};
|
|
shaderCI.EntryPoint = entryPoint;
|
|
|
|
// TODO: Assets management that handles path to assets or something.
|
|
String shaderPath = WrapString("../../../Assets/compiled/Triangle.vert.dxil");
|
|
shaderCI.Stage = ShaderStage::Vertex;
|
|
Shader* vertexShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
|
|
|
|
shaderPath = WrapString("../../../Assets/compiled/SolidColor.frag.dxil");
|
|
shaderCI.Stage = ShaderStage::Fragment;
|
|
Shader* fragmentShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
|
|
|
|
ColorTargetDescription colorTargetDescription = {};
|
|
colorTargetDescription.Format = GetSwapChainTextureFormat(GraphicsDevice, MainWindow);
|
|
|
|
GraphicsPipelineCreateInfo pipelineCI = {};
|
|
pipelineCI.VertexShader = vertexShader;
|
|
pipelineCI.FragmentShader = fragmentShader;
|
|
pipelineCI.PrimitiveType = PrimitiveType::TriangleList;
|
|
pipelineCI.TargetInfo = {
|
|
.ColorTargetDescriptions = &colorTargetDescription,
|
|
.NumColorTargets = 1,
|
|
};
|
|
pipelineCI.RasterizerState.FillMode = FillMode::Solid;
|
|
|
|
GraphicsPipeline* mainPipeline = CreateGraphicsPipeline(GraphicsDevice, pipelineCI);
|
|
|
|
if (vertexShader)
|
|
{
|
|
DestroyShader(GraphicsDevice, vertexShader);
|
|
}
|
|
if (fragmentShader)
|
|
{
|
|
DestroyShader(GraphicsDevice, fragmentShader);
|
|
}
|
|
}
|
|
|
|
GameCode.Functions = reinterpret_cast<void**>(&Game);
|
|
GameCode.FunctionCount = ArraySize(GameFunctionTable);
|
|
GameCode.FunctionNames = GameFunctionTable;
|
|
InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
|
|
if ((Running = GameCode.IsValid))
|
|
{
|
|
Game.Init();
|
|
}
|
|
}
|
|
}
|
|
|
|
void JulietApplication::Shutdown()
|
|
{
|
|
Log(LogLevel::Message, LogCategory::Tool, "Shutting down Juliet Application...");
|
|
|
|
Game.Shutdown();
|
|
ShutdownHotReloadCode(GameCode);
|
|
|
|
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()
|
|
{
|
|
SystemEvent evt;
|
|
while (GetEvent(evt))
|
|
{
|
|
if (evt.Type == EventType::Window_Close_Request)
|
|
{
|
|
if (evt.Data.Window.AssociatedWindowID == GetWindowID(MainWindow))
|
|
{
|
|
Running = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
Game.Update(0.0f);
|
|
|
|
if (ShouldReloadCode(GameCode))
|
|
{
|
|
ReloadCode(GameCode);
|
|
}
|
|
|
|
// Draw here for now
|
|
// 1) Acquire a Command Buffer
|
|
CommandList* cmdList = AcquireCommandList(GraphicsDevice, QueueType::Graphics);
|
|
if (cmdList == nullptr)
|
|
{
|
|
Log(LogLevel::Error, LogCategory::Tool, "Failed to acquire command list.");
|
|
Running = false;
|
|
return;
|
|
}
|
|
|
|
Texture* swapChainTexture = nullptr;
|
|
if (!AcquireSwapChainTexture(cmdList, MainWindow, &swapChainTexture))
|
|
{
|
|
Log(LogLevel::Error, LogCategory::Tool, "Failed to acquire swapchain texture.");
|
|
Running = false;
|
|
return;
|
|
}
|
|
|
|
if (swapChainTexture)
|
|
{
|
|
ColorTargetInfo colorTargetInfo = {};
|
|
colorTargetInfo.TargetTexture = swapChainTexture;
|
|
colorTargetInfo.ClearColor = { .R = .5f, .G = .8f, .B = .0f, .A = 1.f };
|
|
colorTargetInfo.LoadOperation = LoadOperation::Clear;
|
|
colorTargetInfo.StoreOperation = StoreOperation::Store;
|
|
|
|
RenderPass* renderPass = BeginRenderPass(cmdList, colorTargetInfo);
|
|
EndRenderPass(renderPass);
|
|
}
|
|
|
|
// Submit Commands
|
|
SubmitCommandLists(cmdList);
|
|
}
|
|
|
|
bool JulietApplication::IsRunning()
|
|
{
|
|
return Running;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
JulietApplication EditorApplication;
|
|
}
|
|
|
|
JulietApplication& GetEditorApplication()
|
|
{
|
|
return EditorApplication;
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
// Allow only one instance to be launched.
|
|
// Need to create Mutex code in the lib because i dont want to include windows.h in this file anymore
|
|
// CreateMutex(0, false, L"Local\\Juliet.App");
|
|
// if (GetLastError() == ERROR_ALREADY_EXISTS)
|
|
// {
|
|
// MessageBox(nullptr, L"An instance of Juliet is already running.", L"Juliet", MB_OK | MB_ICONEXCLAMATION);
|
|
// return EXIT_FAILURE;
|
|
// }
|
|
|
|
StartApplication(EditorApplication, JulietInit_Flags::Display);
|
|
|
|
// Pause here to not close the console window immediatly on stop
|
|
system("PAUSE");
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|