We got GameObjects / Components and shit
This commit is contained in:
@@ -7,8 +7,7 @@
|
||||
#include "glm/gtx/transform.hpp"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
App::App(): renderer{meshCache, materialCache} {
|
||||
}
|
||||
App::App() {}
|
||||
|
||||
void App::init(const AppParams& params) {
|
||||
m_params = params;
|
||||
@@ -34,132 +33,122 @@ void App::init(const AppParams& params) {
|
||||
}
|
||||
|
||||
gfxDevice.init(window, params.appName, false);
|
||||
materialCache.init(gfxDevice);
|
||||
renderer.init(gfxDevice, params.renderSize);
|
||||
|
||||
//Read whole file
|
||||
auto file = AssetFS::GetInstance().ReadBytes("engine://assetfstest.txt");
|
||||
std::string fileStr(file.begin(), file.end());
|
||||
spdlog::info("Read from assetfstest.txt: {}", fileStr);
|
||||
testMesh.name = "Test Mesh";
|
||||
testMesh.vertices = vertices;
|
||||
testMesh.indices = indices;
|
||||
|
||||
testMeshID = meshCache.addMesh(gfxDevice, testMesh);
|
||||
spdlog::info("TestMesh uploaded with id: {}", testMeshID);
|
||||
|
||||
const auto testimgpath = AssetFS::GetInstance().GetFullPath("engine://textures/kobe.png");
|
||||
auto testimgID = gfxDevice.loadImageFromFile(testimgpath);
|
||||
spdlog::info("Test image loaded with id: {}", testimgID);
|
||||
testMaterialID = materialCache.addMaterial(gfxDevice, {
|
||||
.baseColor = glm::vec3(1.f),
|
||||
.diffuseTexture = testimgID,
|
||||
});
|
||||
spdlog::info("Test material created with id: {}", testMaterialID);
|
||||
|
||||
float aspectRatio = static_cast<float>(params.renderSize.x) / static_cast<float>(params.renderSize.y);
|
||||
camera.setAspectRatio(aspectRatio);
|
||||
|
||||
//Look 90 deg to the right
|
||||
camera.SetRotation(glm::radians(glm::vec2(90.f, 0.f)));
|
||||
|
||||
InputManager::GetInstance().Init();
|
||||
|
||||
customInit();
|
||||
}
|
||||
|
||||
void App::run() {
|
||||
const float FPS = 30.f;
|
||||
const float dt = 1.f / FPS;
|
||||
using clock = std::chrono::steady_clock;
|
||||
|
||||
auto prevTime = std::chrono::high_resolution_clock::now();
|
||||
float accumulator = dt; // so that we get at least 1 update before render
|
||||
const float targetHz = 60.0f;
|
||||
const float dt = 1.0f / targetHz;
|
||||
const float maxFrameTime = 0.25f; // clamp big hitches
|
||||
const int maxSteps = 5; // prevent spiral of death
|
||||
|
||||
auto prevTime = clock::now();
|
||||
float accumulator = 0.0f;
|
||||
|
||||
isRunning = true;
|
||||
while (isRunning) {
|
||||
const auto newTime = std::chrono::high_resolution_clock::now();
|
||||
frameTime = std::chrono::duration<float>(newTime - prevTime).count();
|
||||
const auto frameStart = clock::now();
|
||||
float frameTimeSec = std::chrono::duration<float>(frameStart - prevTime).count();
|
||||
prevTime = frameStart;
|
||||
|
||||
if (frameTime > 0.07f && frameTime < 5.f) {
|
||||
// if >=5.f - debugging?
|
||||
spdlog::warn("Frame drop detected, time: {:.4f}s", frameTime);
|
||||
if (frameTimeSec > 0.07f && frameTimeSec < 5.f) {
|
||||
spdlog::warn("Frame drop detected, time: {:.4f}s", frameTimeSec);
|
||||
}
|
||||
|
||||
accumulator += frameTime;
|
||||
prevTime = newTime;
|
||||
if (frameTimeSec > maxFrameTime) frameTimeSec = maxFrameTime;
|
||||
if (frameTimeSec < 0.0f) frameTimeSec = 0.0f;
|
||||
|
||||
float newFPS = 1.f / frameTime;
|
||||
if (newFPS == std::numeric_limits<float>::infinity()) {
|
||||
// can happen when frameTime == 0
|
||||
newFPS = 0;
|
||||
}
|
||||
avgFPS = std::lerp(avgFPS, newFPS, 0.1f);
|
||||
accumulator += frameTimeSec;
|
||||
|
||||
if (accumulator > 10 * dt) {
|
||||
// game stopped for debug
|
||||
accumulator = dt;
|
||||
if (frameTimeSec > 0.0f) {
|
||||
const float newFPS = 1.0f / frameTimeSec;
|
||||
avgFPS = std::lerp(avgFPS, newFPS, 0.1f);
|
||||
}
|
||||
|
||||
while (accumulator >= dt) {
|
||||
InputManager::GetInstance().BeginFrame();
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
isRunning = false;
|
||||
return;
|
||||
}
|
||||
if (event.type == SDL_WINDOWEVENT) {
|
||||
switch (event.window.event) {
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
/* fallthrough */
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
m_params.windowSize = {event.window.data1, event.window.data2};
|
||||
break;
|
||||
}
|
||||
}
|
||||
InputManager::GetInstance().ProcessEvent(event);
|
||||
|
||||
InputManager::GetInstance().BeginFrame();
|
||||
camera.Update(dt);
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
isRunning = false;
|
||||
break;
|
||||
}
|
||||
|
||||
camera.Update(dt);
|
||||
if (gfxDevice.needsSwapchainRecreate()) {
|
||||
spdlog::info("Recreating swapchain to size: {}x{}", m_params.windowSize.x, m_params.windowSize.y);
|
||||
gfxDevice.recreateSwapchain(m_params.windowSize.x, m_params.windowSize.y);
|
||||
renderer.resize(gfxDevice, { m_params.windowSize.x, m_params.windowSize.y });
|
||||
float aspectRatio = float(m_params.windowSize.x) / float(m_params.windowSize.y);
|
||||
camera.setAspectRatio(aspectRatio);
|
||||
if (event.type == SDL_WINDOWEVENT) {
|
||||
switch (event.window.event) {
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
m_params.windowSize = { event.window.data1, event.window.data2 };
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (InputManager::GetInstance().ProcessEvent(event)) {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
if (!isRunning) break;
|
||||
customUpdate(dt);
|
||||
|
||||
// ---- Swapchain resize check once per frame ----
|
||||
if (gfxDevice.needsSwapchainRecreate()) {
|
||||
spdlog::info("Recreating swapchain to size: {}x{}", m_params.windowSize.x, m_params.windowSize.y);
|
||||
gfxDevice.recreateSwapchain(m_params.windowSize.x, m_params.windowSize.y);
|
||||
onWindowResize(m_params.windowSize.x, m_params.windowSize.y);
|
||||
}
|
||||
|
||||
// ---- Fixed updates (no event polling inside) ----
|
||||
int steps = 0;
|
||||
while (accumulator >= dt && steps < maxSteps) {
|
||||
//Set window title to fps
|
||||
SDL_SetWindowTitle(
|
||||
window,
|
||||
fmt::format("{} - FPS: {:.2f}", m_params.windowTitle, avgFPS).c_str());
|
||||
accumulator -= dt;
|
||||
steps++;
|
||||
}
|
||||
// If we hit the step cap, drop leftover time to recover smoothly
|
||||
if (steps == maxSteps) accumulator = 0.0f;
|
||||
|
||||
// Optional interpolation factor for rendering
|
||||
const float alpha = accumulator / dt;
|
||||
|
||||
// ---- Render ----
|
||||
if (!gfxDevice.needsSwapchainRecreate()) {
|
||||
glm::mat4 objMatrix = glm::mat4(1.f);
|
||||
objMatrix = glm::translate(objMatrix, glm::vec3(0.f, -3.0f, 0.f));
|
||||
renderer.beginDrawing(gfxDevice);
|
||||
renderer.drawMesh(testMeshID, glm::mat4(1.f), testMaterialID);
|
||||
renderer.drawMesh(testMeshID, objMatrix, 0);
|
||||
renderer.endDrawing();
|
||||
|
||||
|
||||
auto cmd = gfxDevice.beginFrame();
|
||||
const auto& drawImage = renderer.getDrawImage(gfxDevice);
|
||||
renderer.draw(cmd, gfxDevice, camera, GameRenderer::SceneData{
|
||||
camera, glm::vec3(0.1f), 0.5f, glm::vec3(0.5f), 0.01f
|
||||
});
|
||||
gfxDevice.endFrame(cmd, drawImage, {
|
||||
.clearColor = {{0.f, 0.f, 0.5f, 1.f}},
|
||||
.drawImageBlitRect = glm::ivec4{}}
|
||||
);
|
||||
// glm::mat4 objMatrix = glm::translate(glm::mat4(1.f), glm::vec3(0.f, -3.0f, 0.f));
|
||||
//
|
||||
// renderer.beginDrawing(gfxDevice);
|
||||
// renderer.drawMesh(testMeshID, glm::mat4(1.f), testMaterialID);
|
||||
// renderer.drawMesh(testMeshID, objMatrix, 0);
|
||||
// renderer.endDrawing();
|
||||
//
|
||||
// const auto cmd = gfxDevice.beginFrame();
|
||||
// const auto& drawImage = renderer.getDrawImage(gfxDevice);
|
||||
//
|
||||
// renderer.draw(cmd, gfxDevice, camera, GameRenderer::SceneData{
|
||||
// camera, glm::vec3(0.1f), 0.5f, glm::vec3(0.5f), 0.01f
|
||||
// });
|
||||
//
|
||||
// gfxDevice.endFrame(cmd, drawImage, {
|
||||
// .clearColor = {{0.f, 0.f, 0.5f, 1.f}},
|
||||
// .drawImageBlitRect = glm::ivec4{}
|
||||
// });
|
||||
customDraw();
|
||||
}
|
||||
|
||||
// ---- Frame cap (if you still want it) ----
|
||||
if (frameLimit) {
|
||||
// Delay to not overload the CPU
|
||||
const auto now = std::chrono::high_resolution_clock::now();
|
||||
const auto frameTime = std::chrono::duration<float>(now - prevTime).count();
|
||||
if (dt > frameTime) {
|
||||
SDL_Delay(static_cast<std::uint32_t>(dt - frameTime));
|
||||
}
|
||||
const auto targetEnd = frameStart + std::chrono::duration_cast<clock::duration>(
|
||||
std::chrono::duration<float>(dt)
|
||||
);
|
||||
std::this_thread::sleep_until(targetEnd);
|
||||
}
|
||||
}
|
||||
gfxDevice.waitIdle();
|
||||
}
|
||||
|
||||
void App::cleanup() {
|
||||
|
||||
Reference in New Issue
Block a user