mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Add vulkan push constant support
This commit is contained in:
parent
d628414d69
commit
99b287309d
@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/vec3.hpp>
|
||||||
#include <glm/ext.hpp>
|
#include <glm/vec4.hpp>
|
||||||
|
#include <glm/mat4x4.hpp>
|
||||||
|
|
||||||
namespace engine::components {
|
namespace engine::components {
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ public:
|
|||||||
~Renderer() override;
|
~Renderer() override;
|
||||||
|
|
||||||
// called every frame, do not call manually
|
// called every frame, do not call manually
|
||||||
void render(glm::mat4 transform);
|
void render(glm::mat4 model);
|
||||||
|
|
||||||
void setMesh(const std::string& name);
|
void setMesh(const std::string& name);
|
||||||
void setTexture(const std::string& name);
|
void setTexture(const std::string& name);
|
||||||
|
@ -21,11 +21,33 @@ namespace engine {
|
|||||||
|
|
||||||
void gameLoop();
|
void gameLoop();
|
||||||
|
|
||||||
|
Window* window()
|
||||||
|
{
|
||||||
|
return m_win;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input* input()
|
||||||
|
{
|
||||||
|
return m_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceManager* resources()
|
||||||
|
{
|
||||||
|
return m_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneRoot* scene()
|
||||||
|
{
|
||||||
|
return m_scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Window> m_win;
|
Window* m_win;
|
||||||
std::unique_ptr<Input> m_input;
|
Input* m_input;
|
||||||
std::unique_ptr<ResourceManager> m_res;
|
ResourceManager* m_res;
|
||||||
std::unique_ptr<SceneRoot> m_scene;
|
SceneRoot* m_scene;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace engine {
|
|||||||
|
|
||||||
// adds a draw call to the queue
|
// adds a draw call to the queue
|
||||||
// vertexBuffer is required, indexBuffer can be NULL, uniformData is required
|
// 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.
|
// Call once per frame. Executes all queued draw calls and renders to the screen.
|
||||||
void renderFrame();
|
void renderFrame();
|
||||||
@ -32,6 +32,8 @@ namespace engine {
|
|||||||
gfx::Pipeline* createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize);
|
gfx::Pipeline* createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize);
|
||||||
void destroyPipeline(const gfx::Pipeline* pipeline);
|
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);
|
gfx::Buffer* createBuffer(gfx::BufferType type, uint64_t size, const void* data);
|
||||||
void destroyBuffer(const gfx::Buffer* buffer);
|
void destroyBuffer(const gfx::Buffer* buffer);
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ namespace engine {
|
|||||||
class Component;
|
class Component;
|
||||||
|
|
||||||
namespace components {
|
namespace components {
|
||||||
class Transform;
|
|
||||||
class Camera;
|
class Camera;
|
||||||
class Renderer;
|
class Renderer;
|
||||||
class UI;
|
class UI;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace engine::gfx {
|
namespace engine::gfx {
|
||||||
class Pipeline;
|
struct Pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace engine::resources {
|
namespace engine::resources {
|
||||||
@ -22,7 +22,8 @@ public:
|
|||||||
~Shader() override;
|
~Shader() override;
|
||||||
|
|
||||||
struct UniformBuffer {
|
struct UniformBuffer {
|
||||||
glm::mat4 transform;
|
glm::mat4 v;
|
||||||
|
glm::mat4 p;
|
||||||
};
|
};
|
||||||
|
|
||||||
gfx::Pipeline* getPipeline()
|
gfx::Pipeline* getPipeline()
|
||||||
|
@ -38,6 +38,14 @@ void Camera::updateCam(glm::mat4 transform)
|
|||||||
|
|
||||||
glm::mat4 viewMatrix = glm::inverse(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;
|
using namespace resources;
|
||||||
|
|
||||||
auto resPtrs = parent.res.getAllResourcesOfType("shader");
|
auto resPtrs = parent.res.getAllResourcesOfType("shader");
|
||||||
@ -46,6 +54,7 @@ void Camera::updateCam(glm::mat4 transform)
|
|||||||
auto lockedPtr = resPtr.lock();
|
auto lockedPtr = resPtr.lock();
|
||||||
auto shader = dynamic_cast<Shader*>(lockedPtr.get());
|
auto shader = dynamic_cast<Shader*>(lockedPtr.get());
|
||||||
// SET VIEW TRANSFORM HERE
|
// SET VIEW TRANSFORM HERE
|
||||||
|
gfxdev->updateUniformBuffer(shader->getPipeline(), &uniformData);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -69,7 +78,8 @@ void Camera::usePerspective(float fovDeg)
|
|||||||
glm::vec2 viewportDim = getViewportSize();
|
glm::vec2 viewportDim = getViewportSize();
|
||||||
|
|
||||||
float fovRad = glm::radians(fovDeg);
|
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()
|
void Camera::useOrtho()
|
||||||
@ -79,7 +89,8 @@ void Camera::useOrtho()
|
|||||||
glm::vec2 viewportDim = getViewportSize();
|
glm::vec2 viewportDim = getViewportSize();
|
||||||
float aspect = viewportDim.x / viewportDim.y;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "gfx_device.hpp"
|
#include "gfx_device.hpp"
|
||||||
|
|
||||||
|
#include "log.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace engine::components {
|
namespace engine::components {
|
||||||
@ -23,11 +25,7 @@ Renderer::~Renderer()
|
|||||||
|
|
||||||
void Renderer::render(glm::mat4 transform)
|
void Renderer::render(glm::mat4 transform)
|
||||||
{
|
{
|
||||||
resources::Shader::UniformBuffer ub {
|
gfxdev->draw(m_shader->getPipeline(), m_mesh->vb, m_mesh->ib, m_mesh->m_vertices.size(), &transform);
|
||||||
glm::mat4{1.0f},
|
|
||||||
};
|
|
||||||
|
|
||||||
gfxdev->draw(m_shader->getPipeline(), m_mesh->vb, m_mesh->ib, m_mesh->m_indices.size(), &ub);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::setMesh(const std::string& name)
|
void Renderer::setMesh(const std::string& name)
|
||||||
|
@ -14,32 +14,34 @@
|
|||||||
#include "components/mesh_renderer.hpp"
|
#include "components/mesh_renderer.hpp"
|
||||||
#include "components/camera.hpp"
|
#include "components/camera.hpp"
|
||||||
|
|
||||||
static engine::gfx::Pipeline* pipeline;
|
|
||||||
static engine::gfx::Buffer* vb;
|
|
||||||
static engine::gfx::Buffer* ib;
|
|
||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
Application::Application(const char* appName, const char* appVersion)
|
Application::Application(const char* appName, const char* appVersion)
|
||||||
{
|
{
|
||||||
m_win = std::make_unique<Window>(appName, true);
|
m_win = new Window(appName, true);
|
||||||
|
|
||||||
gfxdev = new GFXDevice(appName, appVersion, m_win->getHandle());
|
gfxdev = new GFXDevice(appName, appVersion, m_win->getHandle());
|
||||||
m_input = std::make_unique<Input>(*m_win);
|
|
||||||
m_res = std::make_unique<ResourceManager>();
|
|
||||||
GameIO things{};
|
|
||||||
things.win = m_win.get();
|
|
||||||
things.input = m_input.get();
|
|
||||||
things.resMan = m_res.get();
|
|
||||||
m_scene = std::make_unique<SceneRoot>(things);
|
|
||||||
|
|
||||||
m_scene->createChild("player")->createComponent<components::Renderer>()->setMesh("meshes/cube.mesh");
|
m_input = new Input(*m_win);
|
||||||
m_scene->createChild("cam")->createComponent<components::Camera>();
|
m_res = new ResourceManager();
|
||||||
|
|
||||||
|
GameIO things{
|
||||||
|
m_win,
|
||||||
|
m_input,
|
||||||
|
m_res
|
||||||
|
};
|
||||||
|
m_scene = new SceneRoot(things);
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application()
|
Application::~Application()
|
||||||
{
|
{
|
||||||
|
delete m_scene;
|
||||||
|
delete m_res;
|
||||||
|
delete m_input;
|
||||||
|
|
||||||
delete gfxdev;
|
delete gfxdev;
|
||||||
|
|
||||||
|
delete m_win;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::gameLoop()
|
void Application::gameLoop()
|
||||||
|
@ -36,7 +36,7 @@ namespace engine {
|
|||||||
|
|
||||||
static constexpr uint32_t FRAMES_IN_FLIGHT = 2; // This improved FPS by 5x! (on Intel IGPU)
|
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
|
// structures and enums
|
||||||
|
|
||||||
@ -55,6 +55,13 @@ namespace engine {
|
|||||||
VkQueue handle;
|
VkQueue handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct DepthBuffer {
|
||||||
|
VkImage image;
|
||||||
|
VmaAllocation allocation;
|
||||||
|
VkImageView view;
|
||||||
|
};
|
||||||
|
|
||||||
struct Swapchain {
|
struct Swapchain {
|
||||||
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
@ -66,6 +73,8 @@ namespace engine {
|
|||||||
std::vector<VkImageView> imageViews{};
|
std::vector<VkImageView> imageViews{};
|
||||||
std::vector<VkFramebuffer> framebuffers{};
|
std::vector<VkFramebuffer> framebuffers{};
|
||||||
|
|
||||||
|
DepthBuffer depthBuffer{};
|
||||||
|
|
||||||
VkQueue activeQueue{};
|
VkQueue activeQueue{};
|
||||||
|
|
||||||
VkRenderPass renderpass;
|
VkRenderPass renderpass;
|
||||||
@ -78,7 +87,7 @@ namespace engine {
|
|||||||
const gfx::Buffer* vertexBuffer = nullptr;
|
const gfx::Buffer* vertexBuffer = nullptr;
|
||||||
const gfx::Buffer* indexBuffer = nullptr; // if this is nullptr, don't use indexed
|
const gfx::Buffer* indexBuffer = nullptr; // if this is nullptr, don't use indexed
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
uint8_t uniformData[UNIFORM_BUFFER_MAX_SIZE];
|
uint8_t pushConstantData[PUSH_CONSTANT_MAX_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class QueueFlags : uint32_t {
|
enum class QueueFlags : uint32_t {
|
||||||
@ -307,8 +316,59 @@ namespace engine {
|
|||||||
throw std::runtime_error("Unable to find the requested queue");
|
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.
|
// This is called not just on initialisation, but also when the window is resized.
|
||||||
static void createSwapchain(VkDevice device, VkPhysicalDevice physicalDevice, const std::vector<Queue> queues, SDL_Window* window, VkSurfaceKHR surface, Swapchain* swapchain)
|
static void createSwapchain(VkDevice device, VkPhysicalDevice physicalDevice, VmaAllocator allocator, std::vector<Queue> queues, SDL_Window* window, VkSurfaceKHR surface, Swapchain* swapchain)
|
||||||
{
|
{
|
||||||
VkResult res;
|
VkResult res;
|
||||||
|
|
||||||
@ -363,6 +423,8 @@ namespace engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkExtent2D oldExtent = swapchain->extent;
|
||||||
|
|
||||||
if (caps.currentExtent.width != std::numeric_limits<uint32_t>::max()) {
|
if (caps.currentExtent.width != std::numeric_limits<uint32_t>::max()) {
|
||||||
swapchain->extent = caps.currentExtent;
|
swapchain->extent = caps.currentExtent;
|
||||||
}
|
}
|
||||||
@ -435,6 +497,16 @@ namespace engine {
|
|||||||
res = vkGetSwapchainImagesKHR(device, swapchain->swapchain, &swapchainImageCount, swapchain->images.data());
|
res = vkGetSwapchainImagesKHR(device, swapchain->swapchain, &swapchainImageCount, swapchain->images.data());
|
||||||
assert(res == VK_SUCCESS);
|
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
|
// create the render pass
|
||||||
if (swapchain->renderpass == VK_NULL_HANDLE) {
|
if (swapchain->renderpass == VK_NULL_HANDLE) {
|
||||||
VkAttachmentDescription colorAttachment{};
|
VkAttachmentDescription colorAttachment{};
|
||||||
@ -451,26 +523,42 @@ namespace engine {
|
|||||||
colorAttachmentRef.attachment = 0;
|
colorAttachmentRef.attachment = 0;
|
||||||
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
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{};
|
VkSubpassDescription subpass{};
|
||||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
subpass.colorAttachmentCount = 1;
|
subpass.colorAttachmentCount = 1;
|
||||||
subpass.pColorAttachments = &colorAttachmentRef;
|
subpass.pColorAttachments = &colorAttachmentRef;
|
||||||
|
subpass.pDepthStencilAttachment = &depthAttachmentRef;
|
||||||
|
|
||||||
VkSubpassDependency dependency{};
|
VkSubpassDependency dependency{};
|
||||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
dependency.dstSubpass = 0;
|
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.srcAccessMask = 0;
|
||||||
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_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;
|
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
|
std::array<VkAttachmentDescription, 2> attachments = { colorAttachment, depthAttachment };
|
||||||
|
|
||||||
VkRenderPassCreateInfo createInfo{};
|
VkRenderPassCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
createInfo.attachmentCount = 1;
|
createInfo.attachmentCount = (uint32_t)attachments.size();
|
||||||
createInfo.pAttachments = &colorAttachment;
|
createInfo.pAttachments = attachments.data();
|
||||||
createInfo.subpassCount = 1;
|
createInfo.subpassCount = 1;
|
||||||
createInfo.pSubpasses = &subpass;
|
createInfo.pSubpasses = &subpass;
|
||||||
|
|
||||||
createInfo.dependencyCount = 1;
|
createInfo.dependencyCount = 1;
|
||||||
createInfo.pDependencies = &dependency;
|
createInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
@ -505,15 +593,16 @@ namespace engine {
|
|||||||
res = vkCreateImageView(device, &createInfo, nullptr, &swapchain->imageViews[i]);
|
res = vkCreateImageView(device, &createInfo, nullptr, &swapchain->imageViews[i]);
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
|
|
||||||
VkImageView attachments[] = {
|
std::array<VkImageView, 2> attachments = {
|
||||||
swapchain->imageViews[i]
|
swapchain->imageViews[i],
|
||||||
|
swapchain->depthBuffer.view
|
||||||
};
|
};
|
||||||
|
|
||||||
VkFramebufferCreateInfo framebufferInfo{};
|
VkFramebufferCreateInfo framebufferInfo{};
|
||||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
framebufferInfo.renderPass = swapchain->renderpass;
|
framebufferInfo.renderPass = swapchain->renderpass;
|
||||||
framebufferInfo.attachmentCount = 1;
|
framebufferInfo.attachmentCount = (uint32_t)attachments.size();
|
||||||
framebufferInfo.pAttachments = attachments;
|
framebufferInfo.pAttachments = attachments.data();
|
||||||
framebufferInfo.width = swapchain->extent.width;
|
framebufferInfo.width = swapchain->extent.width;
|
||||||
framebufferInfo.height = swapchain->extent.height;
|
framebufferInfo.height = swapchain->extent.height;
|
||||||
framebufferInfo.layers = 1;
|
framebufferInfo.layers = 1;
|
||||||
@ -1022,7 +1111,7 @@ namespace engine {
|
|||||||
|
|
||||||
|
|
||||||
// Now make the swapchain
|
// 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) {
|
for (VkFramebuffer fb : pimpl->swapchain.framebuffers) {
|
||||||
vkDestroyFramebuffer(pimpl->device, fb, nullptr);
|
vkDestroyFramebuffer(pimpl->device, fb, nullptr);
|
||||||
}
|
}
|
||||||
|
destroyDepthBuffer(pimpl->swapchain.depthBuffer, pimpl->device, pimpl->allocator);
|
||||||
vkDestroyRenderPass(pimpl->device, pimpl->swapchain.renderpass, nullptr);
|
vkDestroyRenderPass(pimpl->device, pimpl->swapchain.renderpass, nullptr);
|
||||||
vkDestroySwapchainKHR(pimpl->device, pimpl->swapchain.swapchain, nullptr);
|
vkDestroySwapchainKHR(pimpl->device, pimpl->swapchain.swapchain, nullptr);
|
||||||
|
|
||||||
@ -1089,12 +1179,11 @@ namespace engine {
|
|||||||
*h = pimpl->swapchain.extent.height;
|
*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->type == gfx::BufferType::VERTEX);
|
||||||
assert(vertexBuffer != nullptr);
|
assert(vertexBuffer != nullptr);
|
||||||
assert(indexBuffer == nullptr || indexBuffer->type == gfx::BufferType::INDEX);
|
assert(indexBuffer == nullptr || indexBuffer->type == gfx::BufferType::INDEX);
|
||||||
assert(uniformData != nullptr);
|
|
||||||
|
|
||||||
DrawCall call{
|
DrawCall call{
|
||||||
.vertexBuffer = vertexBuffer,
|
.vertexBuffer = vertexBuffer,
|
||||||
@ -1102,9 +1191,7 @@ namespace engine {
|
|||||||
.count = count,
|
.count = count,
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t uniformDataSize = pipeline->uniformBuffers[pimpl->FRAMECOUNT % FRAMES_IN_FLIGHT]->size;
|
memcpy(call.pushConstantData, pushConstantData, PUSH_CONSTANT_MAX_SIZE);
|
||||||
|
|
||||||
memcpy(call.uniformData, uniformData, uniformDataSize);
|
|
||||||
|
|
||||||
pimpl->drawQueues[pipeline].push(call);
|
pimpl->drawQueues[pipeline].push(call);
|
||||||
|
|
||||||
@ -1126,7 +1213,7 @@ namespace engine {
|
|||||||
if (res == VK_ERROR_OUT_OF_DATE_KHR) {
|
if (res == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||||
// recreate swapchain
|
// recreate swapchain
|
||||||
waitIdle();
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1150,9 +1237,11 @@ namespace engine {
|
|||||||
renderPassInfo.renderArea.offset = { 0, 0 };
|
renderPassInfo.renderArea.offset = { 0, 0 };
|
||||||
renderPassInfo.renderArea.extent = pimpl->swapchain.extent;
|
renderPassInfo.renderArea.extent = pimpl->swapchain.extent;
|
||||||
|
|
||||||
VkClearValue clearColor{ {0.0f, 0.0f, 0.0f, 0.0f} };
|
std::array<VkClearValue, 2> clearValues{};
|
||||||
renderPassInfo.clearValueCount = 1;
|
clearValues[0].color = { {0.0f, 0.0f, 0.0f, 1.0f} };
|
||||||
renderPassInfo.pClearValues = &clearColor;
|
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);
|
vkCmdBeginRenderPass(pimpl->commandBuffers[frameIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
@ -1181,13 +1270,7 @@ namespace engine {
|
|||||||
|
|
||||||
DrawCall call = queue.front();
|
DrawCall call = queue.front();
|
||||||
|
|
||||||
void* uniformDest;
|
vkCmdPushConstants(pimpl->commandBuffers[frameIndex], pipeline->layout, VK_SHADER_STAGE_VERTEX_BIT, 0, PUSH_CONSTANT_MAX_SIZE, call.pushConstantData);
|
||||||
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);
|
|
||||||
|
|
||||||
vkCmdBindVertexBuffers(pimpl->commandBuffers[frameIndex], 0, 1, &call.vertexBuffer->buffer, offsets);
|
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) {
|
if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||||
// recreate swapchain
|
// recreate swapchain
|
||||||
waitIdle();
|
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 {
|
else {
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
@ -1405,7 +1488,7 @@ namespace engine {
|
|||||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
rasterizer.lineWidth = 1.0f;
|
rasterizer.lineWidth = 1.0f;
|
||||||
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
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.depthBiasEnable = VK_FALSE;
|
||||||
rasterizer.depthBiasConstantFactor = 0.0f; // ignored
|
rasterizer.depthBiasConstantFactor = 0.0f; // ignored
|
||||||
rasterizer.depthBiasClamp = 0.0f; // ignored
|
rasterizer.depthBiasClamp = 0.0f; // ignored
|
||||||
@ -1445,12 +1528,29 @@ namespace engine {
|
|||||||
colorBlending.blendConstants[2] = 0.0f; // ignored
|
colorBlending.blendConstants[2] = 0.0f; // ignored
|
||||||
colorBlending.blendConstants[3] = 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{};
|
VkPipelineLayoutCreateInfo layoutInfo{};
|
||||||
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
layoutInfo.setLayoutCount = 1;
|
layoutInfo.setLayoutCount = 1;
|
||||||
layoutInfo.pSetLayouts = &pimpl->uboLayout;
|
layoutInfo.pSetLayouts = &pimpl->uboLayout;
|
||||||
layoutInfo.pushConstantRangeCount = 0;
|
layoutInfo.pushConstantRangeCount = 1;
|
||||||
layoutInfo.pPushConstantRanges = nullptr;
|
layoutInfo.pPushConstantRanges = &pushConstantRange;
|
||||||
|
|
||||||
res = vkCreatePipelineLayout(pimpl->device, &layoutInfo, nullptr, &pipeline->layout);
|
res = vkCreatePipelineLayout(pimpl->device, &layoutInfo, nullptr, &pipeline->layout);
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
@ -1464,7 +1564,7 @@ namespace engine {
|
|||||||
createInfo.pViewportState = &viewportState;
|
createInfo.pViewportState = &viewportState;
|
||||||
createInfo.pRasterizationState = &rasterizer;
|
createInfo.pRasterizationState = &rasterizer;
|
||||||
createInfo.pMultisampleState = &multisampling;
|
createInfo.pMultisampleState = &multisampling;
|
||||||
createInfo.pDepthStencilState = nullptr;
|
createInfo.pDepthStencilState = &depthStencil;
|
||||||
createInfo.pColorBlendState = &colorBlending;
|
createInfo.pColorBlendState = &colorBlending;
|
||||||
createInfo.pDynamicState = &dynamicState;
|
createInfo.pDynamicState = &dynamicState;
|
||||||
createInfo.layout = pipeline->layout;
|
createInfo.layout = pipeline->layout;
|
||||||
@ -1498,6 +1598,20 @@ namespace engine {
|
|||||||
delete pipeline;
|
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)
|
gfx::Buffer* GFXDevice::createBuffer(gfx::BufferType type, uint64_t size, const void* data)
|
||||||
{
|
{
|
||||||
VkResult res;
|
VkResult res;
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <log.hpp>
|
#include <log.hpp>
|
||||||
|
|
||||||
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
int Object::s_object_count = 0;
|
int Object::s_object_count = 0;
|
||||||
@ -109,7 +111,7 @@ namespace engine {
|
|||||||
// scale (effectively applied first
|
// scale (effectively applied first
|
||||||
objTransform = glm::scale(objTransform, t.scale);
|
objTransform = glm::scale(objTransform, t.scale);
|
||||||
|
|
||||||
const glm::mat4 newTransform = parentTransform * objTransform;
|
glm::mat4 newTransform = parentTransform * objTransform;
|
||||||
|
|
||||||
for (const auto& compUnq : m_components) {
|
for (const auto& compUnq : m_components) {
|
||||||
const auto comp = compUnq.get();
|
const auto comp = compUnq.get();
|
||||||
|
@ -35,6 +35,8 @@ namespace engine {
|
|||||||
if (std::filesystem::is_directory(m_resourcesPath) == false) {
|
if (std::filesystem::is_directory(m_resourcesPath) == false) {
|
||||||
throw std::runtime_error("Unable to determine resources location. CWD: " + cwd.string());
|
throw std::runtime_error("Unable to determine resources location. CWD: " + cwd.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_resourcesPath = "C:/Users/Bailey/source/repos/game/res";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<std::string> ResourceManager::getResourcesListString()
|
std::unique_ptr<std::string> ResourceManager::getResourcesListString()
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
namespace engine::resources {
|
namespace engine::resources {
|
||||||
|
|
||||||
struct MeshFileHeader {
|
struct MeshFileHeader {
|
||||||
unsigned int vertex_count;
|
uint32_t vertex_count;
|
||||||
unsigned int index_count;
|
uint32_t index_count;
|
||||||
int material;
|
int32_t material;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void loadMeshFromFile(const std::filesystem::path& path, std::vector<Vertex>* vertices, std::vector<uint32_t>* indices)
|
static void loadMeshFromFile(const std::filesystem::path& path, std::vector<Vertex>* vertices, std::vector<uint32_t>* indices)
|
||||||
@ -30,7 +30,7 @@ static void loadMeshFromFile(const std::filesystem::path& path, std::vector<Vert
|
|||||||
indices->resize(header.index_count);
|
indices->resize(header.index_count);
|
||||||
vertices->resize(header.vertex_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);
|
fread(vertices->data(), sizeof(float) * 8 * header.vertex_count, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
@ -41,11 +41,19 @@ void Mesh::initMesh()
|
|||||||
vb = gfxdev->createBuffer(gfx::BufferType::VERTEX, m_vertices.size() * sizeof(Vertex), m_vertices.data());
|
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());
|
ib = gfxdev->createBuffer(gfx::BufferType::INDEX, m_indices.size() * sizeof(uint32_t), m_indices.data());
|
||||||
|
|
||||||
|
TRACE("VB PTR in mesh: {}", (void*)vb);
|
||||||
|
|
||||||
TRACE("Vertices:");
|
TRACE("Vertices:");
|
||||||
|
|
||||||
for (const auto& v : m_vertices) {
|
for (const auto& v : m_vertices) {
|
||||||
TRACE("pos: {}, {}, {}", v.pos.x, v.pos.y, v.pos.z);
|
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<Vertex>& vertices) : Resource("", "mesh")
|
Mesh::Mesh(const std::vector<Vertex>& vertices) : Resource("", "mesh")
|
||||||
|
@ -30,6 +30,7 @@ Shader::Shader(const std::filesystem::path& resPath) : Resource(resPath, "shader
|
|||||||
{
|
{
|
||||||
|
|
||||||
gfx::VertexFormat vertexFormat {};
|
gfx::VertexFormat vertexFormat {};
|
||||||
|
vertexFormat.stride = 8 * sizeof(float);
|
||||||
vertexFormat.attributeDescriptions.emplace_back(0, gfx::VertexAttribFormat::VEC3, 0); // pos
|
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(1, gfx::VertexAttribFormat::VEC3, sizeof(glm::vec3)); // norm
|
||||||
vertexFormat.attributeDescriptions.emplace_back(2, gfx::VertexAttribFormat::VEC2, sizeof(glm::vec3) + sizeof(glm::vec3)); // uv
|
vertexFormat.attributeDescriptions.emplace_back(2, gfx::VertexAttribFormat::VEC2, sizeof(glm::vec3) + sizeof(glm::vec3)); // uv
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "components/mesh_renderer.hpp"
|
#include "components/mesh_renderer.hpp"
|
||||||
#include "components/text_ui_renderer.hpp"
|
#include "components/text_ui_renderer.hpp"
|
||||||
|
|
||||||
|
#include "gfx_device.hpp"
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -46,12 +48,12 @@ namespace engine {
|
|||||||
|
|
||||||
// render
|
// render
|
||||||
|
|
||||||
for (const auto& [c, t] : compList.cameras) {
|
for (const auto& [c, camt] : compList.cameras) {
|
||||||
for (int id : m_activeCameras) {
|
for (int id : m_activeCameras) {
|
||||||
if (c->getID() == id) {
|
if (c->getID() == id) {
|
||||||
c->updateCam(t);
|
c->updateCam(camt);
|
||||||
for (const auto& [c, t] : compList.renderers) {
|
for (const auto& [ren, ren_t] : compList.renderers) {
|
||||||
c->render(t);
|
ren->render(ren_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user