diff --git a/include/components/camera.hpp b/include/components/camera.hpp index 4e6db0d..e5f4e6a 100644 --- a/include/components/camera.hpp +++ b/include/components/camera.hpp @@ -8,8 +8,9 @@ #include -#include -#include +#include +#include +#include namespace engine::components { diff --git a/include/components/mesh_renderer.hpp b/include/components/mesh_renderer.hpp index 43a468f..588e7ce 100644 --- a/include/components/mesh_renderer.hpp +++ b/include/components/mesh_renderer.hpp @@ -21,7 +21,7 @@ public: ~Renderer() override; // called every frame, do not call manually - void render(glm::mat4 transform); + void render(glm::mat4 model); void setMesh(const std::string& name); void setTexture(const std::string& name); diff --git a/include/engine.hpp b/include/engine.hpp index 3361fd7..809ecea 100644 --- a/include/engine.hpp +++ b/include/engine.hpp @@ -21,11 +21,33 @@ namespace engine { void gameLoop(); + Window* window() + { + return m_win; + } + + Input* input() + { + return m_input; + } + + ResourceManager* resources() + { + return m_res; + } + + SceneRoot* scene() + { + return m_scene; + } + + + private: - std::unique_ptr m_win; - std::unique_ptr m_input; - std::unique_ptr m_res; - std::unique_ptr m_scene; + Window* m_win; + Input* m_input; + ResourceManager* m_res; + SceneRoot* m_scene; }; } diff --git a/include/gfx_device.hpp b/include/gfx_device.hpp index a5106c2..5d8ca33 100644 --- a/include/gfx_device.hpp +++ b/include/gfx_device.hpp @@ -23,7 +23,7 @@ namespace engine { // adds a draw call to the queue // vertexBuffer is required, indexBuffer can be NULL, uniformData is required - void draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* uniformData); + void draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* pushConstantData); // Call once per frame. Executes all queued draw calls and renders to the screen. void renderFrame(); @@ -32,6 +32,8 @@ namespace engine { gfx::Pipeline* createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize); void destroyPipeline(const gfx::Pipeline* pipeline); + void updateUniformBuffer(const gfx::Pipeline* pipeline, void* data); + gfx::Buffer* createBuffer(gfx::BufferType type, uint64_t size, const void* data); void destroyBuffer(const gfx::Buffer* buffer); diff --git a/include/object.hpp b/include/object.hpp index 86105c4..b6c4f71 100644 --- a/include/object.hpp +++ b/include/object.hpp @@ -23,7 +23,6 @@ namespace engine { class Component; namespace components { - class Transform; class Camera; class Renderer; class UI; diff --git a/include/resources/shader.hpp b/include/resources/shader.hpp index 5b88253..e547c82 100644 --- a/include/resources/shader.hpp +++ b/include/resources/shader.hpp @@ -10,7 +10,7 @@ #include namespace engine::gfx { - class Pipeline; + struct Pipeline; } namespace engine::resources { @@ -22,7 +22,8 @@ public: ~Shader() override; struct UniformBuffer { - glm::mat4 transform; + glm::mat4 v; + glm::mat4 p; }; gfx::Pipeline* getPipeline() diff --git a/src/components/camera.cpp b/src/components/camera.cpp index 4c786f9..d5b3ff3 100644 --- a/src/components/camera.cpp +++ b/src/components/camera.cpp @@ -38,6 +38,14 @@ void Camera::updateCam(glm::mat4 transform) glm::mat4 viewMatrix = glm::inverse(transform); + struct { + glm::mat4 view; + glm::mat4 proj; + } uniformData{}; + + uniformData.view = viewMatrix; + uniformData.proj = m_projMatrix; + using namespace resources; auto resPtrs = parent.res.getAllResourcesOfType("shader"); @@ -46,6 +54,7 @@ void Camera::updateCam(glm::mat4 transform) auto lockedPtr = resPtr.lock(); auto shader = dynamic_cast(lockedPtr.get()); // SET VIEW TRANSFORM HERE + gfxdev->updateUniformBuffer(shader->getPipeline(), &uniformData); } } @@ -69,7 +78,8 @@ void Camera::usePerspective(float fovDeg) glm::vec2 viewportDim = getViewportSize(); float fovRad = glm::radians(fovDeg); - m_projMatrix = glm::perspectiveFov(fovRad, viewportDim.x, viewportDim.y, NEAR, FAR); + m_projMatrix = glm::perspectiveFovRH_ZO(fovRad, viewportDim.x, viewportDim.y, NEAR, FAR); + m_projMatrix[1][1] *= -1; } void Camera::useOrtho() @@ -79,7 +89,8 @@ void Camera::useOrtho() glm::vec2 viewportDim = getViewportSize(); float aspect = viewportDim.x / viewportDim.y; - m_projMatrix = glm::ortho(-10.0f * aspect, 10.0f * aspect, -10.0f, 10.0f, -100.0f, 100.0f); + m_projMatrix = glm::orthoRH_ZO(-10.0f * aspect, 10.0f * aspect, -10.0f, 10.0f, -100.0f, 100.0f); + m_projMatrix[1][1] *= -1; } } diff --git a/src/components/mesh_renderer.cpp b/src/components/mesh_renderer.cpp index a4e8e17..fa4deb4 100644 --- a/src/components/mesh_renderer.cpp +++ b/src/components/mesh_renderer.cpp @@ -6,6 +6,8 @@ #include "gfx_device.hpp" +#include "log.hpp" + #include namespace engine::components { @@ -23,11 +25,7 @@ Renderer::~Renderer() void Renderer::render(glm::mat4 transform) { - resources::Shader::UniformBuffer ub { - glm::mat4{1.0f}, - }; - - gfxdev->draw(m_shader->getPipeline(), m_mesh->vb, m_mesh->ib, m_mesh->m_indices.size(), &ub); + gfxdev->draw(m_shader->getPipeline(), m_mesh->vb, m_mesh->ib, m_mesh->m_vertices.size(), &transform); } void Renderer::setMesh(const std::string& name) diff --git a/src/engine.cpp b/src/engine.cpp index 86d9c36..1ecc2c9 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -14,32 +14,34 @@ #include "components/mesh_renderer.hpp" #include "components/camera.hpp" -static engine::gfx::Pipeline* pipeline; -static engine::gfx::Buffer* vb; -static engine::gfx::Buffer* ib; - namespace engine { Application::Application(const char* appName, const char* appVersion) { - m_win = std::make_unique(appName, true); + m_win = new Window(appName, true); gfxdev = new GFXDevice(appName, appVersion, m_win->getHandle()); - m_input = std::make_unique(*m_win); - m_res = std::make_unique(); - GameIO things{}; - things.win = m_win.get(); - things.input = m_input.get(); - things.resMan = m_res.get(); - m_scene = std::make_unique(things); - m_scene->createChild("player")->createComponent()->setMesh("meshes/cube.mesh"); - m_scene->createChild("cam")->createComponent(); + m_input = new Input(*m_win); + m_res = new ResourceManager(); + + GameIO things{ + m_win, + m_input, + m_res + }; + m_scene = new SceneRoot(things); } Application::~Application() { + delete m_scene; + delete m_res; + delete m_input; + delete gfxdev; + + delete m_win; } void Application::gameLoop() diff --git a/src/gfx_device_vulkan.cpp b/src/gfx_device_vulkan.cpp index 79fe32e..133abb2 100644 --- a/src/gfx_device_vulkan.cpp +++ b/src/gfx_device_vulkan.cpp @@ -36,7 +36,7 @@ namespace engine { static constexpr uint32_t FRAMES_IN_FLIGHT = 2; // This improved FPS by 5x! (on Intel IGPU) - static constexpr size_t UNIFORM_BUFFER_MAX_SIZE = 256; // bytes + static constexpr size_t PUSH_CONSTANT_MAX_SIZE = 128; // bytes // structures and enums @@ -55,6 +55,13 @@ namespace engine { VkQueue handle; }; + + struct DepthBuffer { + VkImage image; + VmaAllocation allocation; + VkImageView view; + }; + struct Swapchain { VkSwapchainKHR swapchain = VK_NULL_HANDLE; @@ -66,6 +73,8 @@ namespace engine { std::vector imageViews{}; std::vector framebuffers{}; + DepthBuffer depthBuffer{}; + VkQueue activeQueue{}; VkRenderPass renderpass; @@ -78,7 +87,7 @@ namespace engine { const gfx::Buffer* vertexBuffer = nullptr; const gfx::Buffer* indexBuffer = nullptr; // if this is nullptr, don't use indexed uint32_t count = 0; - uint8_t uniformData[UNIFORM_BUFFER_MAX_SIZE]; + uint8_t pushConstantData[PUSH_CONSTANT_MAX_SIZE]; }; enum class QueueFlags : uint32_t { @@ -307,8 +316,59 @@ namespace engine { throw std::runtime_error("Unable to find the requested queue"); } + static DepthBuffer createDepthBuffer(VkDevice device, VmaAllocator allocator, VkExtent2D extent) + { + DepthBuffer db{}; + + VkResult res; + + VkImageCreateInfo imageInfo{}; + imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.extent.width = extent.width; + imageInfo.extent.height = extent.height; + imageInfo.extent.depth = 1; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = 1; + imageInfo.format = VK_FORMAT_D32_SFLOAT; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.flags = 0; + + VmaAllocationCreateInfo allocInfo{}; + allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + allocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + allocInfo.priority = 1.0f; + + res = vmaCreateImage(allocator, &imageInfo, &allocInfo, &db.image, &db.allocation, nullptr); + assert(res == VK_SUCCESS); + + VkImageViewCreateInfo imageViewInfo{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; + imageViewInfo.image = db.image; + imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + imageViewInfo.format = VK_FORMAT_D32_SFLOAT; + imageViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + imageViewInfo.subresourceRange.baseMipLevel = 0; + imageViewInfo.subresourceRange.levelCount = 1; + imageViewInfo.subresourceRange.baseArrayLayer = 0; + imageViewInfo.subresourceRange.layerCount = 1; + res = vkCreateImageView(device, &imageViewInfo, nullptr, &db.view); + assert(res == VK_SUCCESS); + + return db; + } + + static void destroyDepthBuffer(DepthBuffer db, VkDevice device, VmaAllocator allocator) + { + vkDestroyImageView(device, db.view, nullptr); + vmaDestroyImage(allocator, db.image, db.allocation); + } + // This is called not just on initialisation, but also when the window is resized. - static void createSwapchain(VkDevice device, VkPhysicalDevice physicalDevice, const std::vector queues, SDL_Window* window, VkSurfaceKHR surface, Swapchain* swapchain) + static void createSwapchain(VkDevice device, VkPhysicalDevice physicalDevice, VmaAllocator allocator, std::vector queues, SDL_Window* window, VkSurfaceKHR surface, Swapchain* swapchain) { VkResult res; @@ -363,6 +423,8 @@ namespace engine { } } + VkExtent2D oldExtent = swapchain->extent; + if (caps.currentExtent.width != std::numeric_limits::max()) { swapchain->extent = caps.currentExtent; } @@ -435,6 +497,16 @@ namespace engine { res = vkGetSwapchainImagesKHR(device, swapchain->swapchain, &swapchainImageCount, swapchain->images.data()); assert(res == VK_SUCCESS); + // create depth buffer if old depth buffer is wrong size + if (swapchain->swapchain == VK_NULL_HANDLE) { + swapchain->depthBuffer = createDepthBuffer(device, allocator, swapchain->extent); + } + else if (swapchain->extent.width != oldExtent.width || swapchain->extent.height != oldExtent.height) { + destroyDepthBuffer(swapchain->depthBuffer, device, allocator); + swapchain->depthBuffer = createDepthBuffer(device, allocator, swapchain->extent); + } + + // create the render pass if (swapchain->renderpass == VK_NULL_HANDLE) { VkAttachmentDescription colorAttachment{}; @@ -451,26 +523,42 @@ namespace engine { colorAttachmentRef.attachment = 0; colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkAttachmentDescription depthAttachment{}; + depthAttachment.format = VK_FORMAT_D32_SFLOAT; + depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; + depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkAttachmentReference depthAttachmentRef{}; + depthAttachmentRef.attachment = 1; + depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + VkSubpassDescription subpass{}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorAttachmentRef; + subpass.pDepthStencilAttachment = &depthAttachmentRef; VkSubpassDependency dependency{}; dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; dependency.srcAccessMask = 0; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + + std::array attachments = { colorAttachment, depthAttachment }; VkRenderPassCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - createInfo.attachmentCount = 1; - createInfo.pAttachments = &colorAttachment; + createInfo.attachmentCount = (uint32_t)attachments.size(); + createInfo.pAttachments = attachments.data(); createInfo.subpassCount = 1; createInfo.pSubpasses = &subpass; - createInfo.dependencyCount = 1; createInfo.pDependencies = &dependency; @@ -505,15 +593,16 @@ namespace engine { res = vkCreateImageView(device, &createInfo, nullptr, &swapchain->imageViews[i]); assert(res == VK_SUCCESS); - VkImageView attachments[] = { - swapchain->imageViews[i] + std::array attachments = { + swapchain->imageViews[i], + swapchain->depthBuffer.view }; VkFramebufferCreateInfo framebufferInfo{}; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.renderPass = swapchain->renderpass; - framebufferInfo.attachmentCount = 1; - framebufferInfo.pAttachments = attachments; + framebufferInfo.attachmentCount = (uint32_t)attachments.size(); + framebufferInfo.pAttachments = attachments.data(); framebufferInfo.width = swapchain->extent.width; framebufferInfo.height = swapchain->extent.height; framebufferInfo.layers = 1; @@ -1022,7 +1111,7 @@ namespace engine { // Now make the swapchain - createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->queues, window, pimpl->surface, &pimpl->swapchain); + createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, window, pimpl->surface, &pimpl->swapchain); @@ -1071,6 +1160,7 @@ namespace engine { for (VkFramebuffer fb : pimpl->swapchain.framebuffers) { vkDestroyFramebuffer(pimpl->device, fb, nullptr); } + destroyDepthBuffer(pimpl->swapchain.depthBuffer, pimpl->device, pimpl->allocator); vkDestroyRenderPass(pimpl->device, pimpl->swapchain.renderpass, nullptr); vkDestroySwapchainKHR(pimpl->device, pimpl->swapchain.swapchain, nullptr); @@ -1089,12 +1179,11 @@ namespace engine { *h = pimpl->swapchain.extent.height; } - void GFXDevice::draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* uniformData) + void GFXDevice::draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* pushConstantData) { assert(vertexBuffer->type == gfx::BufferType::VERTEX); assert(vertexBuffer != nullptr); assert(indexBuffer == nullptr || indexBuffer->type == gfx::BufferType::INDEX); - assert(uniformData != nullptr); DrawCall call{ .vertexBuffer = vertexBuffer, @@ -1102,9 +1191,7 @@ namespace engine { .count = count, }; - size_t uniformDataSize = pipeline->uniformBuffers[pimpl->FRAMECOUNT % FRAMES_IN_FLIGHT]->size; - - memcpy(call.uniformData, uniformData, uniformDataSize); + memcpy(call.pushConstantData, pushConstantData, PUSH_CONSTANT_MAX_SIZE); pimpl->drawQueues[pipeline].push(call); @@ -1126,7 +1213,7 @@ namespace engine { if (res == VK_ERROR_OUT_OF_DATE_KHR) { // recreate swapchain waitIdle(); - createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->queues, pimpl->window, pimpl->surface, &pimpl->swapchain); + createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, pimpl->window, pimpl->surface, &pimpl->swapchain); return; } else { @@ -1150,9 +1237,11 @@ namespace engine { renderPassInfo.renderArea.offset = { 0, 0 }; renderPassInfo.renderArea.extent = pimpl->swapchain.extent; - VkClearValue clearColor{ {0.0f, 0.0f, 0.0f, 0.0f} }; - renderPassInfo.clearValueCount = 1; - renderPassInfo.pClearValues = &clearColor; + std::array clearValues{}; + clearValues[0].color = { {0.0f, 0.0f, 0.0f, 1.0f} }; + clearValues[1].depthStencil = { 1.0f, 0 }; + renderPassInfo.clearValueCount = (uint32_t)clearValues.size(); + renderPassInfo.pClearValues = clearValues.data(); vkCmdBeginRenderPass(pimpl->commandBuffers[frameIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); @@ -1181,13 +1270,7 @@ namespace engine { DrawCall call = queue.front(); - void* uniformDest; - res = vmaMapMemory(pimpl->allocator, pipeline->uniformBuffers[frameIndex]->allocation, &uniformDest); - assert(res == VK_SUCCESS); - - memcpy(uniformDest, call.uniformData, pipeline->uniformBuffers[frameIndex]->size); - - vmaUnmapMemory(pimpl->allocator, pipeline->uniformBuffers[frameIndex]->allocation); + vkCmdPushConstants(pimpl->commandBuffers[frameIndex], pipeline->layout, VK_SHADER_STAGE_VERTEX_BIT, 0, PUSH_CONSTANT_MAX_SIZE, call.pushConstantData); vkCmdBindVertexBuffers(pimpl->commandBuffers[frameIndex], 0, 1, &call.vertexBuffer->buffer, offsets); @@ -1239,7 +1322,7 @@ namespace engine { if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) { // recreate swapchain waitIdle(); - createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->queues, pimpl->window, pimpl->surface, &pimpl->swapchain); + createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, pimpl->window, pimpl->surface, &pimpl->swapchain); } else { assert(res == VK_SUCCESS); @@ -1405,7 +1488,7 @@ namespace engine { rasterizer.polygonMode = VK_POLYGON_MODE_FILL; rasterizer.lineWidth = 1.0f; rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; - rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterizer.depthBiasEnable = VK_FALSE; rasterizer.depthBiasConstantFactor = 0.0f; // ignored rasterizer.depthBiasClamp = 0.0f; // ignored @@ -1445,12 +1528,29 @@ namespace engine { colorBlending.blendConstants[2] = 0.0f; // ignored colorBlending.blendConstants[3] = 0.0f; // ignored + VkPipelineDepthStencilStateCreateInfo depthStencil{}; + depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + depthStencil.depthTestEnable = VK_TRUE; + depthStencil.depthWriteEnable = VK_TRUE; + depthStencil.depthCompareOp = VK_COMPARE_OP_LESS; + depthStencil.depthBoundsTestEnable = VK_FALSE; + depthStencil.minDepthBounds = 0.0f; + depthStencil.maxDepthBounds = 1.0f; + depthStencil.stencilTestEnable = VK_FALSE; + depthStencil.front = {}; + depthStencil.back = {}; + + VkPushConstantRange pushConstantRange{}; + pushConstantRange.offset = 0; + pushConstantRange.size = PUSH_CONSTANT_MAX_SIZE; + pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + VkPipelineLayoutCreateInfo layoutInfo{}; layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layoutInfo.setLayoutCount = 1; layoutInfo.pSetLayouts = &pimpl->uboLayout; - layoutInfo.pushConstantRangeCount = 0; - layoutInfo.pPushConstantRanges = nullptr; + layoutInfo.pushConstantRangeCount = 1; + layoutInfo.pPushConstantRanges = &pushConstantRange; res = vkCreatePipelineLayout(pimpl->device, &layoutInfo, nullptr, &pipeline->layout); assert(res == VK_SUCCESS); @@ -1464,7 +1564,7 @@ namespace engine { createInfo.pViewportState = &viewportState; createInfo.pRasterizationState = &rasterizer; createInfo.pMultisampleState = &multisampling; - createInfo.pDepthStencilState = nullptr; + createInfo.pDepthStencilState = &depthStencil; createInfo.pColorBlendState = &colorBlending; createInfo.pDynamicState = &dynamicState; createInfo.layout = pipeline->layout; @@ -1498,6 +1598,20 @@ namespace engine { delete pipeline; } + void GFXDevice::updateUniformBuffer(const gfx::Pipeline* pipeline, void* data) + { + VkResult res; + + void* uniformDest; + for (gfx::Buffer* buffer : pipeline->uniformBuffers) { + res = vmaMapMemory(pimpl->allocator, buffer->allocation, &uniformDest); + assert(res == VK_SUCCESS); + memcpy(uniformDest, data, buffer->size); + vmaUnmapMemory(pimpl->allocator, buffer->allocation); + } + + } + gfx::Buffer* GFXDevice::createBuffer(gfx::BufferType type, uint64_t size, const void* data) { VkResult res; diff --git a/src/object.cpp b/src/object.cpp index 11d74d3..46efc52 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -7,6 +7,8 @@ #include +#include + namespace engine { int Object::s_object_count = 0; @@ -109,7 +111,7 @@ namespace engine { // scale (effectively applied first objTransform = glm::scale(objTransform, t.scale); - const glm::mat4 newTransform = parentTransform * objTransform; + glm::mat4 newTransform = parentTransform * objTransform; for (const auto& compUnq : m_components) { const auto comp = compUnq.get(); diff --git a/src/resource_manager.cpp b/src/resource_manager.cpp index dfef6da..6d0ee8c 100644 --- a/src/resource_manager.cpp +++ b/src/resource_manager.cpp @@ -35,6 +35,8 @@ namespace engine { if (std::filesystem::is_directory(m_resourcesPath) == false) { throw std::runtime_error("Unable to determine resources location. CWD: " + cwd.string()); } + + m_resourcesPath = "C:/Users/Bailey/source/repos/game/res"; } std::unique_ptr ResourceManager::getResourcesListString() diff --git a/src/resources/mesh.cpp b/src/resources/mesh.cpp index a70ce8d..8d276a9 100644 --- a/src/resources/mesh.cpp +++ b/src/resources/mesh.cpp @@ -7,9 +7,9 @@ namespace engine::resources { struct MeshFileHeader { - unsigned int vertex_count; - unsigned int index_count; - int material; + uint32_t vertex_count; + uint32_t index_count; + int32_t material; }; static void loadMeshFromFile(const std::filesystem::path& path, std::vector* vertices, std::vector* indices) @@ -30,7 +30,7 @@ static void loadMeshFromFile(const std::filesystem::path& path, std::vectorresize(header.index_count); vertices->resize(header.vertex_count); - fread(indices->data(), sizeof(unsigned int) * header.index_count, 1, fp); + fread(indices->data(), sizeof(uint32_t) * header.index_count, 1, fp); fread(vertices->data(), sizeof(float) * 8 * header.vertex_count, 1, fp); fclose(fp); @@ -41,11 +41,19 @@ void Mesh::initMesh() vb = gfxdev->createBuffer(gfx::BufferType::VERTEX, m_vertices.size() * sizeof(Vertex), m_vertices.data()); ib = gfxdev->createBuffer(gfx::BufferType::INDEX, m_indices.size() * sizeof(uint32_t), m_indices.data()); + TRACE("VB PTR in mesh: {}", (void*)vb); + TRACE("Vertices:"); for (const auto& v : m_vertices) { TRACE("pos: {}, {}, {}", v.pos.x, v.pos.y, v.pos.z); } + + TRACE("Indices:"); + + for (const uint32_t i : m_indices) { + TRACE("\t{}", i); + } } Mesh::Mesh(const std::vector& vertices) : Resource("", "mesh") diff --git a/src/resources/shader.cpp b/src/resources/shader.cpp index 8c62b16..25c643e 100644 --- a/src/resources/shader.cpp +++ b/src/resources/shader.cpp @@ -30,6 +30,7 @@ Shader::Shader(const std::filesystem::path& resPath) : Resource(resPath, "shader { gfx::VertexFormat vertexFormat {}; + vertexFormat.stride = 8 * sizeof(float); vertexFormat.attributeDescriptions.emplace_back(0, gfx::VertexAttribFormat::VEC3, 0); // pos vertexFormat.attributeDescriptions.emplace_back(1, gfx::VertexAttribFormat::VEC3, sizeof(glm::vec3)); // norm vertexFormat.attributeDescriptions.emplace_back(2, gfx::VertexAttribFormat::VEC2, sizeof(glm::vec3) + sizeof(glm::vec3)); // uv diff --git a/src/sceneroot.cpp b/src/sceneroot.cpp index 31ac13d..5b8f1dc 100644 --- a/src/sceneroot.cpp +++ b/src/sceneroot.cpp @@ -7,6 +7,8 @@ #include "components/mesh_renderer.hpp" #include "components/text_ui_renderer.hpp" +#include "gfx_device.hpp" + #include #include @@ -46,12 +48,12 @@ namespace engine { // render - for (const auto& [c, t] : compList.cameras) { + for (const auto& [c, camt] : compList.cameras) { for (int id : m_activeCameras) { if (c->getID() == id) { - c->updateCam(t); - for (const auto& [c, t] : compList.renderers) { - c->render(t); + c->updateCam(camt); + for (const auto& [ren, ren_t] : compList.renderers) { + ren->render(ren_t); } break;