We got GameObjects / Components and shit
This commit is contained in:
@@ -1,4 +1,108 @@
|
||||
#include "Lightkeeper.h"
|
||||
|
||||
LightKeeper::LightKeeper() {
|
||||
#include <destrum/FS/AssetFS.h>
|
||||
#include "glm/gtx/transform.hpp"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <destrum/Scene/Scene.h>
|
||||
|
||||
#include "destrum/Components/MeshRendererComponent.h"
|
||||
#include "destrum/Components/Rotator.h"
|
||||
#include "destrum/ObjectModel/GameObject.h"
|
||||
|
||||
LightKeeper::LightKeeper(): App(), renderer(meshCache, materialCache) {
|
||||
|
||||
}
|
||||
|
||||
LightKeeper::~LightKeeper() {
|
||||
}
|
||||
|
||||
void LightKeeper::customInit() {
|
||||
materialCache.init(gfxDevice);
|
||||
renderer.init(gfxDevice, m_params.renderSize);
|
||||
|
||||
const float aspectRatio = static_cast<float>(m_params.renderSize.x) / static_cast<float>(m_params.renderSize.y);
|
||||
camera.setAspectRatio(aspectRatio);
|
||||
|
||||
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);
|
||||
|
||||
camera.SetRotation(glm::radians(glm::vec2(90.f, 0.f)));
|
||||
|
||||
auto& scene = SceneManager::GetInstance().CreateScene("Main");
|
||||
|
||||
auto testCube = std::make_shared<GameObject>("TestCube");
|
||||
auto meshComp = testCube->AddComponent<MeshRendererComponent>();
|
||||
meshComp->SetMeshID(testMeshID);
|
||||
meshComp->SetMaterialID(testMaterialID);
|
||||
|
||||
testCube->AddComponent<Rotator>(10, 5);
|
||||
|
||||
|
||||
scene.Add(testCube);
|
||||
}
|
||||
|
||||
void LightKeeper::customUpdate(float dt) {
|
||||
camera.Update(dt);
|
||||
SceneManager::GetInstance().Update();
|
||||
}
|
||||
|
||||
void LightKeeper::customDraw() {
|
||||
|
||||
renderer.beginDrawing(gfxDevice);
|
||||
|
||||
const RenderContext ctx{
|
||||
.renderer = renderer,
|
||||
.camera = camera,
|
||||
.sceneData = {
|
||||
.camera = camera,
|
||||
.ambientColor = glm::vec3(0.1f),
|
||||
.ambientIntensity = 0.5f,
|
||||
.fogColor = glm::vec3(0.5f),
|
||||
.fogDensity = 0.01f
|
||||
}
|
||||
};
|
||||
|
||||
SceneManager::GetInstance().Render(ctx);
|
||||
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{}
|
||||
});
|
||||
}
|
||||
|
||||
void LightKeeper::customCleanup() {
|
||||
SceneManager::GetInstance().Destroy();
|
||||
renderer.cleanup(gfxDevice.getDevice().device);
|
||||
}
|
||||
|
||||
void LightKeeper::onWindowResize(int newWidth, int newHeight) {
|
||||
renderer.resize(gfxDevice, glm::ivec2{newWidth, newHeight});
|
||||
const float aspectRatio = static_cast<float>(newWidth) / static_cast<float>(newHeight);
|
||||
camera.setAspectRatio(aspectRatio);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ int main(int argc, char* argv[]) {
|
||||
.exeDir = exeDir,
|
||||
});
|
||||
app.run();
|
||||
app.cleanup();
|
||||
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL_vulkan.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <VkBootstrap.h>
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <volk.h>
|
||||
|
||||
const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
struct FrameData {
|
||||
VkSemaphore imageAvailable;
|
||||
VkSemaphore renderFinished;
|
||||
VkFence inFlight;
|
||||
VkCommandBuffer commandBuffer;
|
||||
};
|
||||
|
||||
SDL_Window* window = nullptr;
|
||||
VkInstance instance;
|
||||
vkb::PhysicalDevice physicalDevice;
|
||||
VkDevice device;
|
||||
vkb::Device vkbDevice;
|
||||
VkQueue graphicsQueue;
|
||||
VkQueue presentQueue;
|
||||
VkSurfaceKHR surface;
|
||||
VkSwapchainKHR swapchain;
|
||||
std::vector<VkImage> swapchainImages;
|
||||
std::vector<VkImageView> swapchainImageViews;
|
||||
VkCommandPool commandPool;
|
||||
FrameData frames[MAX_FRAMES_IN_FLIGHT];
|
||||
std::vector<VkFence> imagesInFlight;
|
||||
size_t currentFrame = 0;
|
||||
VkFormat swapchainImageFormat;
|
||||
VkExtent2D swapchainExtent;
|
||||
|
||||
// --- Helper: allocate command buffer ---
|
||||
VkCommandBuffer allocateCommandBuffer(VkDevice device, VkCommandPool pool) {
|
||||
VkCommandBufferAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.commandPool = pool;
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandBufferCount = 1;
|
||||
|
||||
VkCommandBuffer cmd;
|
||||
vkAllocateCommandBuffers(device, &allocInfo, &cmd);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// --- Helper: record command buffer with dynamic rendering ---
|
||||
void recordCommandBuffer(VkCommandBuffer cmd, VkImage image) {
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
vkBeginCommandBuffer(cmd, &beginInfo);
|
||||
|
||||
VkRenderingAttachmentInfo colorAttachment{};
|
||||
colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
|
||||
colorAttachment.imageView = VK_NULL_HANDLE; // placeholder, normally swapchainImageViews[i]
|
||||
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
VkClearValue clearColor{ {{0.1f, 0.2f, 0.3f, 1.0f}} };
|
||||
colorAttachment.clearValue = clearColor;
|
||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
||||
VkRenderingInfo renderingInfo{};
|
||||
renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
|
||||
renderingInfo.renderArea.offset = {0, 0};
|
||||
renderingInfo.renderArea.extent = {800, 600};
|
||||
renderingInfo.layerCount = 1;
|
||||
renderingInfo.colorAttachmentCount = 1;
|
||||
renderingInfo.pColorAttachments = &colorAttachment;
|
||||
|
||||
vkCmdBeginRendering(cmd, &renderingInfo);
|
||||
// No draw calls, just clear
|
||||
vkCmdEndRendering(cmd);
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
}
|
||||
|
||||
int SDL_main(int argc, char* argv[]) {
|
||||
// --- SDL Window ---
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
throw std::runtime_error("SDL_Init failed");
|
||||
|
||||
window = SDL_CreateWindow("Vulkan SDL Dynamic Rendering",
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
800, 600,
|
||||
SDL_WINDOW_VULKAN);
|
||||
|
||||
// --- Vulkan instance ---
|
||||
volkInitialize();
|
||||
vkb::InstanceBuilder builder;
|
||||
auto instRet = builder.set_app_name("SDL Dynamic Rendering")
|
||||
.request_validation_layers(true)
|
||||
.build();
|
||||
if (!instRet) throw std::runtime_error("Failed to create instance");
|
||||
instance = instRet.value().instance;
|
||||
|
||||
if (!SDL_Vulkan_CreateSurface(window, instance, &surface))
|
||||
throw std::runtime_error("Failed to create Vulkan surface");
|
||||
|
||||
// --- Physical device & logical device ---
|
||||
vkb::PhysicalDeviceSelector selector{instRet.value()};
|
||||
auto physRet = selector.set_minimum_version(1,2).set_surface(surface).require_dedicated_transfer_queue().select();
|
||||
if (!physRet) throw std::runtime_error("Failed to select physical device");
|
||||
physicalDevice = physRet.value();
|
||||
|
||||
vkb::DeviceBuilder deviceBuilder{physicalDevice};
|
||||
auto devRet = deviceBuilder.build();
|
||||
if (!devRet) throw std::runtime_error("Failed to create device");
|
||||
device = devRet.value().device;
|
||||
vkbDevice = devRet.value();
|
||||
graphicsQueue = devRet.value().get_queue(vkb::QueueType::graphics).value();
|
||||
presentQueue = devRet.value().get_queue(vkb::QueueType::present).value();
|
||||
|
||||
// --- Swapchain ---
|
||||
vkb::SwapchainBuilder swapchainBuilder{vkbDevice};
|
||||
auto swapRet = swapchainBuilder.set_desired_format(VkSurfaceFormatKHR{
|
||||
.format = VK_FORMAT_B8G8R8A8_SRGB,
|
||||
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
|
||||
})
|
||||
.set_desired_present_mode(VK_PRESENT_MODE_FIFO_KHR)
|
||||
.set_desired_extent(800,600)
|
||||
.build();
|
||||
if (!swapRet) throw std::runtime_error("Failed to create swapchain");
|
||||
|
||||
swapchain = swapRet.value().swapchain;
|
||||
swapchainImages = swapRet.value().get_images().value();
|
||||
swapchainImageFormat = swapRet.value().image_format;
|
||||
swapchainExtent = swapRet.value().extent;
|
||||
|
||||
// --- Command pool ---
|
||||
VkCommandPoolCreateInfo poolInfo{};
|
||||
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
poolInfo.queueFamilyIndex = vkbDevice.get_queue_index(vkb::QueueType::graphics).value();
|
||||
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool);
|
||||
|
||||
// --- Frames ---
|
||||
imagesInFlight.resize(swapchainImages.size(), VK_NULL_HANDLE);
|
||||
for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||
VkSemaphoreCreateInfo semInfo{};
|
||||
semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
vkCreateSemaphore(device, &semInfo, nullptr, &frames[i].imageAvailable);
|
||||
vkCreateSemaphore(device, &semInfo, nullptr, &frames[i].renderFinished);
|
||||
|
||||
VkFenceCreateInfo fenceInfo{};
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
vkCreateFence(device, &fenceInfo, nullptr, &frames[i].inFlight);
|
||||
|
||||
frames[i].commandBuffer = allocateCommandBuffer(device, commandPool);
|
||||
}
|
||||
|
||||
// --- Main loop ---
|
||||
bool running = true;
|
||||
while (running) {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) running = false;
|
||||
}
|
||||
|
||||
FrameData& frame = frames[currentFrame];
|
||||
|
||||
vkWaitForFences(device, 1, &frame.inFlight, VK_TRUE, UINT64_MAX);
|
||||
|
||||
uint32_t imageIndex;
|
||||
vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, frame.imageAvailable, VK_NULL_HANDLE, &imageIndex);
|
||||
|
||||
if (imagesInFlight[imageIndex] != VK_NULL_HANDLE)
|
||||
vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
|
||||
imagesInFlight[imageIndex] = frame.inFlight;
|
||||
|
||||
vkResetFences(device, 1, &frame.inFlight);
|
||||
vkResetCommandBuffer(frame.commandBuffer, 0);
|
||||
recordCommandBuffer(frame.commandBuffer, swapchainImages[imageIndex]);
|
||||
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
VkSemaphore waitSemaphores[] = { frame.imageAvailable };
|
||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
submitInfo.waitSemaphoreCount = 1;
|
||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||
submitInfo.pWaitDstStageMask = waitStages;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &frame.commandBuffer;
|
||||
VkSemaphore signalSemaphores[] = { frame.renderFinished };
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||
|
||||
vkQueueSubmit(graphicsQueue, 1, &submitInfo, frame.inFlight);
|
||||
|
||||
VkPresentInfoKHR presentInfo{};
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
presentInfo.pWaitSemaphores = signalSemaphores;
|
||||
presentInfo.swapchainCount = 1;
|
||||
presentInfo.pSwapchains = &swapchain;
|
||||
presentInfo.pImageIndices = &imageIndex;
|
||||
|
||||
vkQueuePresentKHR(presentQueue, &presentInfo);
|
||||
|
||||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||
}
|
||||
|
||||
vkDeviceWaitIdle(device);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user