diff --git a/include/application.hpp b/include/application.hpp index 2611171..d00e0a6 100644 --- a/include/application.hpp +++ b/include/application.hpp @@ -31,8 +31,8 @@ namespace engine { const gfx::DescriptorSetLayout* setZeroLayout; const gfx::DescriptorSet* setZero; struct SetZeroBuffer { + glm::mat4 view; glm::mat4 proj; - glm::vec2 myValue; }; gfx::DescriptorBuffer* setZeroBuffer; }; diff --git a/res/engine/shaders/skybox.vert b/res/engine/shaders/skybox.vert index b3a20cd..2e0f9b3 100644 --- a/res/engine/shaders/skybox.vert +++ b/res/engine/shaders/skybox.vert @@ -2,12 +2,11 @@ layout( push_constant ) uniform Constants { mat4 model; - mat4 view; } constants; layout(set = 0, binding = 0) uniform SetZeroBuffer { + mat4 view; mat4 proj; - vec2 myValue; } setZeroBuffer; layout(location = 0) in vec3 inPosition; @@ -16,7 +15,7 @@ layout(location = 2) in vec2 inUV; layout(location = 0) out vec2 fragUV; void main() { - mat4 myView = constants.view; + mat4 myView = setZeroBuffer.view; myView[3] = vec4(0.0, 0.0, 0.0, 1.0); vec4 pos = setZeroBuffer.proj * myView * constants.model * vec4(inPosition, 1.0); gl_Position = pos; diff --git a/res/engine/shaders/standard.vert b/res/engine/shaders/standard.vert index 6bd0aed..e113334 100644 --- a/res/engine/shaders/standard.vert +++ b/res/engine/shaders/standard.vert @@ -2,12 +2,11 @@ layout( push_constant ) uniform Constants { mat4 model; - mat4 view; } constants; layout(set = 0, binding = 0) uniform SetZeroBuffer { + mat4 view; mat4 proj; - vec2 myValue; } setZeroBuffer; layout(location = 0) in vec3 inPosition; @@ -20,12 +19,12 @@ layout(location = 2) out vec2 fragUV; layout(location = 3) out vec3 fragLightPos; void main() { - gl_Position = setZeroBuffer.proj * constants.view * constants.model * vec4(inPosition, 1.0); + gl_Position = setZeroBuffer.proj * setZeroBuffer.view * constants.model * vec4(inPosition, 1.0); - fragPos = vec3(constants.view * constants.model * vec4(inPosition, 1.0)); - fragNorm = mat3(transpose(inverse(constants.view * constants.model))) * inNorm; + fragPos = vec3(setZeroBuffer.view * constants.model * vec4(inPosition, 1.0)); + fragNorm = mat3(transpose(inverse(setZeroBuffer.view * constants.model))) * inNorm; fragUV = inUV; vec3 lightPos = vec3(2000.0, 2000.0, -2000.0); - fragLightPos = vec3(constants.view * vec4(lightPos, 1.0)); + fragLightPos = vec3(setZeroBuffer.view * vec4(lightPos, 1.0)); } diff --git a/src/application.cpp b/src/application.cpp index d6fb716..8f5d41b 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -78,8 +78,8 @@ namespace engine { renderData.setZeroLayout = gfx()->createDescriptorSetLayout(); renderData.setZero = gfx()->allocateDescriptorSet(renderData.setZeroLayout); RenderData::SetZeroBuffer initialData{ + .view = glm::mat4{1.0f}, .proj = glm::perspectiveZO(glm::radians(70.0f), 1024.0f / 768.0f, 0.1f, 1000.0f), - .myValue = { 0.0f, 1.0f } }; renderData.setZeroBuffer = gfx()->createDescriptorBuffer(sizeof(RenderData::SetZeroBuffer), &initialData); gfx()->updateDescriptor(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer)); diff --git a/src/gfx_device_vulkan.cpp b/src/gfx_device_vulkan.cpp index 1fde7c1..4d847f9 100644 --- a/src/gfx_device_vulkan.cpp +++ b/src/gfx_device_vulkan.cpp @@ -613,6 +613,7 @@ namespace engine { pimpl->allocator = createAllocator(pimpl->instance.instance, pimpl->device.device, pimpl->device.physicalDevice); pimpl->swapchainInfo.device = pimpl->device.device; + pimpl->swapchainInfo.allocator = pimpl->allocator; pimpl->swapchainInfo.physicalDevice = pimpl->device.physicalDevice; pimpl->swapchainInfo.surface = pimpl->surface; pimpl->swapchainInfo.window = pimpl->window; diff --git a/src/systems/render.cpp b/src/systems/render.cpp index d2ea093..33d0ca3 100644 --- a/src/systems/render.cpp +++ b/src/systems/render.cpp @@ -47,11 +47,10 @@ namespace engine { const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar); /* update SET 0 */ - RenderData::SetZeroBuffer uniform{}; - uniform.proj = projMatrix; - uniform.myValue.x = 1.0f; - m_value = glm::mod(m_value + ts, 1.0f); - uniform.myValue.y = m_value; + RenderData::SetZeroBuffer uniform{ + .view = viewMatrix, + .proj = projMatrix + }; m_gfx->writeDescriptorBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &uniform); /* render all renderable entities */ @@ -69,11 +68,9 @@ namespace engine { struct { glm::mat4 model; - glm::mat4 view; } pushConsts{}; pushConsts.model = t->worldMatrix; - pushConsts.view = viewMatrix; m_gfx->cmdBindPipeline(renderData.drawBuffer, r->material->getShader()->getPipeline()); m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, r->material->getShader()->getPipeline(), renderData.setZero, 0); diff --git a/src/vulkan/device.cpp b/src/vulkan/device.cpp index 8868747..c6529b8 100644 --- a/src/vulkan/device.cpp +++ b/src/vulkan/device.cpp @@ -5,10 +5,21 @@ #include #include +#include "log.hpp" + #include "device.h" namespace engine { + static bool checkQueueFamilySupportsPresent(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t familyIndex) + { + VkBool32 supportsPresent; + VkResult res; + res = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, static_cast(familyIndex), surface, &supportsPresent); + if (res != VK_SUCCESS) throw std::runtime_error("Failed to check for queue family present support!"); + return supportsPresent; + } + /* chooses a device, creates it, gets its function pointers, and creates command pools */ Device createDevice(VkInstance instance, DeviceRequirements requirements, VkSurfaceKHR surface) { @@ -209,22 +220,33 @@ namespace engine { for (size_t i = 0; i < queueFamilies.size(); i++) { VkQueueFamilyProperties p = queueFamilies[i]; - if (p.queueCount < 2) continue; // need one queue for presenting and one-or-more for rendering + if (p.queueCount < 2) continue; // ideally have one queue for presenting and at least one other for rendering if (p.queueFlags & VK_QUEUE_GRAPHICS_BIT) { - VkBool32 supportsPresent; - res = vkGetPhysicalDeviceSurfaceSupportKHR(d.physicalDevice, static_cast(i), surface, &supportsPresent); - if (res != VK_SUCCESS) throw std::runtime_error("Failed to check for queue family present support!"); - if (supportsPresent) { + if (checkQueueFamilySupportsPresent(d.physicalDevice, surface, i)) { graphicsFamily = static_cast(i); break; } } } - if (graphicsFamily == UINT32_MAX) throw std::runtime_error("Unable to find a graphics/present queue family!"); + if (graphicsFamily == UINT32_MAX) { + for (size_t i = 0; i < queueFamilies.size(); i++) { + VkQueueFamilyProperties p = queueFamilies[i]; + if (p.queueFlags & VK_QUEUE_GRAPHICS_BIT) { + if (checkQueueFamilySupportsPresent(d.physicalDevice, surface, i)) { + graphicsFamily = static_cast(i); + } + } + } + if (graphicsFamily == UINT32_MAX) { + throw std::runtime_error("Failed to find a graphics/present family!"); + } + LOG_WARN("Failed to find ideal graphics/present queue family! Falling back to family #{}.", graphicsFamily); + } // find a transfer queue family (image layout transitions, buffer upload) uint32_t transferFamily = UINT32_MAX; + // prefer a dedicated transfer queue family for (size_t i = 0; i < queueFamilies.size(); i++) { VkQueueFamilyProperties p = queueFamilies[i]; if (((p.queueFlags & VK_QUEUE_TRANSFER_BIT) != 0) && @@ -234,7 +256,10 @@ namespace engine { break; } } - if (transferFamily == UINT32_MAX) throw std::runtime_error("Unable to find a transfer queue family!"); + if (transferFamily == UINT32_MAX) { + transferFamily = graphicsFamily; + LOG_WARN("Failed to find a dedicated transfer queue family! Falling back to graphics family."); + } // queue priorities std::vector graphicsQueuePriorities(queueFamilies[graphicsFamily].queueCount); @@ -242,24 +267,26 @@ namespace engine { std::vector transferQueuePriorities(queueFamilies[transferFamily].queueCount); std::fill(transferQueuePriorities.begin(), transferQueuePriorities.end(), 1.0f); - std::array queueCreateInfos{ - VkDeviceQueueCreateInfo{ - .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .queueFamilyIndex = graphicsFamily, - .queueCount = queueFamilies[graphicsFamily].queueCount, - .pQueuePriorities = graphicsQueuePriorities.data(), - }, - VkDeviceQueueCreateInfo{ + std::vector queueCreateInfos{}; + queueCreateInfos.push_back(VkDeviceQueueCreateInfo{ + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .queueFamilyIndex = graphicsFamily, + .queueCount = queueFamilies[graphicsFamily].queueCount, + .pQueuePriorities = graphicsQueuePriorities.data() + }); + + if (transferFamily != graphicsFamily) { + queueCreateInfos.push_back(VkDeviceQueueCreateInfo{ .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .pNext = nullptr, .flags = 0, .queueFamilyIndex = transferFamily, .queueCount = queueFamilies[transferFamily].queueCount, - .pQueuePriorities = transferQueuePriorities.data(), - } - }; + .pQueuePriorities = transferQueuePriorities.data() + }); + } /* create device now */ VkDeviceCreateInfo deviceCreateInfo{ @@ -282,14 +309,49 @@ namespace engine { volkLoadDevice(d.device); - vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue); - d.queues.drawQueues.resize(queueFamilies[graphicsFamily].queueCount - 1); - for (uint32_t i = 0; i < d.queues.drawQueues.size(); i++) { - vkGetDeviceQueue(d.device, graphicsFamily, i + 1, &d.queues.drawQueues[i]); - } - d.queues.transferQueues.resize(queueFamilies[transferFamily].queueCount); - for (uint32_t i = 0; i < d.queues.transferQueues.size(); i++) { - vkGetDeviceQueue(d.device, transferFamily, i, &d.queues.transferQueues[i]); + + if (transferFamily != graphicsFamily) { + vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue); + if (queueFamilies[graphicsFamily].queueCount >= 2) { + d.queues.drawQueues.resize(queueFamilies[graphicsFamily].queueCount - 1); + for (uint32_t i = 0; i < d.queues.drawQueues.size(); i++) { + vkGetDeviceQueue(d.device, graphicsFamily, i + 1, &d.queues.drawQueues[i]); + } + } else { + d.queues.drawQueues.resize(1); + d.queues.drawQueues[0] = d.queues.presentQueue; + } + d.queues.transferQueues.resize(queueFamilies[transferFamily].queueCount); + for (uint32_t i = 0; i < d.queues.transferQueues.size(); i++) { + vkGetDeviceQueue(d.device, transferFamily, i, &d.queues.transferQueues[i]); + } + } else { + // same graphics family for graphics/present and transfer + uint32_t queueCount = queueFamilies[graphicsFamily].queueCount; + vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue); + if (queueCount >= 2) { + d.queues.transferQueues.resize(1); + vkGetDeviceQueue(d.device, graphicsFamily, 1, &d.queues.transferQueues[0]); + // use the remaining queues for drawing + if (queueCount >= 3) { + d.queues.drawQueues.resize(queueCount - 2); + for (uint32_t i = 0; i < queueCount - 2; i++) { + vkGetDeviceQueue(d.device, graphicsFamily, i + 2, &d.queues.drawQueues[i]); + } + } else { + // 2 queues available + // present and drawing share a queue + // transfer gets its own queue + d.queues.drawQueues.resize(1); + d.queues.drawQueues[0] = d.queues.presentQueue; + } + } else { + // only 1 queue available :( + d.queues.transferQueues.resize(1); + d.queues.transferQueues[0] = d.queues.presentQueue; + d.queues.drawQueues.resize(1); + d.queues.drawQueues[0] = d.queues.presentQueue; + } } d.queues.presentAndDrawQueueFamily = graphicsFamily; diff --git a/src/vulkan/swapchain.cpp b/src/vulkan/swapchain.cpp index 2c527dc..3179f9d 100644 --- a/src/vulkan/swapchain.cpp +++ b/src/vulkan/swapchain.cpp @@ -14,6 +14,7 @@ namespace engine { void createSwapchain(Swapchain* sc, const SwapchainInfo& info) { sc->device = info.device; + sc->allocator = info.allocator; LOG_INFO("Recreating swapchain!\n"); @@ -129,6 +130,61 @@ namespace engine { vkDestroySwapchainKHR(info.device, scInfo.oldSwapchain, nullptr); } + { /* create the depth buffer */ + + sc->depthStencil.format = VK_FORMAT_D32_SFLOAT; + + if (sc->depthStencil.image != VK_NULL_HANDLE) { + vkDestroyImageView(info.device, sc->depthStencil.view, nullptr); + vmaDestroyImage(sc->allocator, sc->depthStencil.image, sc->depthStencil.allocation); + } + VkImageCreateInfo imageInfo{}; + imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageInfo.pNext = nullptr; + imageInfo.flags = 0; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.format = sc->depthStencil.format; + imageInfo.extent.width = sc->extent.width; + imageInfo.extent.height = sc->extent.height; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = 1; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageInfo.queueFamilyIndexCount = 0; // ignored + imageInfo.pQueueFamilyIndices = nullptr; // ignored + imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VmaAllocationCreateInfo allocInfo{}; + allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + allocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + allocInfo.priority = 1.0f; + + res = vmaCreateImage(sc->allocator, &imageInfo, &allocInfo, &sc->depthStencil.image, &sc->depthStencil.allocation, nullptr); + if (res != VK_SUCCESS) throw std::runtime_error("Failed to create depth buffer image! Code: " + std::to_string(res)); + + VkImageViewCreateInfo viewInfo{}; + viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + viewInfo.pNext = nullptr; + viewInfo.flags = 0; + viewInfo.image = sc->depthStencil.image; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.format = sc->depthStencil.format; + viewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + viewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + viewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + viewInfo.subresourceRange.baseMipLevel = 0; + viewInfo.subresourceRange.levelCount = 1; + viewInfo.subresourceRange.baseArrayLayer = 0; + viewInfo.subresourceRange.layerCount = 1; + res = vkCreateImageView(info.device, &viewInfo, nullptr, &sc->depthStencil.view); + assert(res == VK_SUCCESS); + + } + /* create the render pass */ if (sc->renderpass != VK_NULL_HANDLE) { vkDestroyRenderPass(sc->device, sc->renderpass, nullptr); @@ -144,10 +200,26 @@ namespace engine { .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR }; + VkAttachmentDescription depthStencilAttachment{ + .flags = 0, + .format = sc->depthStencil.format, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // the depth buffer is not used after the fragment shader + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, // ignored + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // ignored + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + }; + std::array attachments { colorAttachment, depthStencilAttachment }; VkAttachmentReference colorAttachmentRef{ .attachment = 0, .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + VkAttachmentReference depthStencilAttachmentRef{ + .attachment = 1, + .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + }; VkSubpassDescription subpass{ .flags = 0, .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, @@ -156,25 +228,25 @@ namespace engine { .colorAttachmentCount = 1, .pColorAttachments = &colorAttachmentRef, .pResolveAttachments = nullptr, - .pDepthStencilAttachment = nullptr, + .pDepthStencilAttachment = &depthStencilAttachmentRef, .preserveAttachmentCount = 0, .pPreserveAttachments = nullptr, }; VkSubpassDependency dependency{ .srcSubpass = VK_SUBPASS_EXTERNAL, .dstSubpass = 0, - .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dependencyFlags = 0 }; VkRenderPassCreateInfo renderPassInfo{ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, .pNext = nullptr, .flags = 0, - .attachmentCount = 1, - .pAttachments = &colorAttachment, + .attachmentCount = attachments.size(), + .pAttachments = attachments.data(), .subpassCount = 1, .pSubpasses = &subpass, .dependencyCount = 1, @@ -194,9 +266,9 @@ namespace engine { /* create image view and framebuffer for each image */ sc->images.resize(swapchainImageCount); for (uint32_t i = 0; i < swapchainImageCount; i++) { - auto& [image, view, framebuffer] = sc->images.at(i); + auto& [image, imageView, framebuffer] = sc->images.at(i); - if (view != VK_NULL_HANDLE) vkDestroyImageView(sc->device, view, nullptr); + if (imageView != VK_NULL_HANDLE) vkDestroyImageView(sc->device, imageView, nullptr); if (framebuffer != VK_NULL_HANDLE) vkDestroyFramebuffer(sc->device, framebuffer, nullptr); image = swapchainImages[i]; @@ -218,16 +290,20 @@ namespace engine { viewInfo.subresourceRange.levelCount = 1; viewInfo.subresourceRange.baseArrayLayer = 0; viewInfo.subresourceRange.layerCount = 1; - VkResult res = vkCreateImageView(sc->device, &viewInfo, nullptr, &view); + VkResult res = vkCreateImageView(sc->device, &viewInfo, nullptr, &imageView); if (res != VK_SUCCESS) throw std::runtime_error("Failed to create image view from swapchain image!"); + std::array attachments { + imageView, sc->depthStencil.view + }; + VkFramebufferCreateInfo fbInfo{}; fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fbInfo.pNext = nullptr; fbInfo.flags = 0; fbInfo.renderPass = sc->renderpass; - fbInfo.attachmentCount = 1; - fbInfo.pAttachments = &view; + fbInfo.attachmentCount = attachments.size(); + fbInfo.pAttachments = attachments.data(); fbInfo.width = sc->extent.width; fbInfo.height = sc->extent.height; fbInfo.layers = 1; @@ -246,7 +322,9 @@ namespace engine { vkDestroyImageView(sc.device, view, nullptr); } vkDestroyRenderPass(sc.device, sc.renderpass, nullptr); + vkDestroyImageView(sc.device, sc.depthStencil.view, nullptr); + vmaDestroyImage(sc.allocator, sc.depthStencil.image, sc.depthStencil.allocation); vkDestroySwapchainKHR(sc.device, sc.swapchain, nullptr); } -} \ No newline at end of file +} diff --git a/src/vulkan/swapchain.h b/src/vulkan/swapchain.h index 1dea4f2..a784868 100644 --- a/src/vulkan/swapchain.h +++ b/src/vulkan/swapchain.h @@ -1,22 +1,32 @@ #pragma once #include +#include #include #include +#include + namespace engine { struct Swapchain { VkSwapchainKHR swapchain = VK_NULL_HANDLE; VkDevice device = VK_NULL_HANDLE; // the associated device + VmaAllocator allocator = VK_NULL_HANDLE; // the associated allocator VkSurfaceFormatKHR surfaceFormat{}; VkSurfaceCapabilitiesKHR surfaceCapabilities{}; VkPresentModeKHR presentMode{}; VkExtent2D extent{}; VkRenderPass renderpass = VK_NULL_HANDLE; std::vector> images{}; + struct DepthStencil { + VkImage image = VK_NULL_HANDLE; + VmaAllocation allocation = VK_NULL_HANDLE; + VkImageView view = VK_NULL_HANDLE; + VkFormat format{}; + } depthStencil{}; }; struct SwapchainInfo { @@ -24,6 +34,7 @@ namespace engine { VkPhysicalDevice physicalDevice; VkSurfaceKHR surface; SDL_Window* window; + VmaAllocator allocator; bool vsync; bool waitForPresent; }; diff --git a/test/src/game.cpp b/test/src/game.cpp index 5e16f48..a8415a3 100644 --- a/test/src/game.cpp +++ b/test/src/game.cpp @@ -107,7 +107,7 @@ void playGame(bool enableFrameLimiter) /* cube */ { uint32_t cube = myScene->createEntity("cube"); - myScene->getComponent(cube)->position = glm::vec3{ -0.5f, -0.5f, -0.5f }; + myScene->getComponent(cube)->position = glm::vec3{ -0.5f, -0.5f + 5.0f, -0.5f }; auto cubeRenderable = myScene->addComponent(cube); cubeRenderable->material = std::make_shared(app.getResource("builtin.standard")); cubeRenderable->mesh = genCuboidMesh(app.gfx(), 1.0f, 1.0f, 1.0f, 1);