Skip to content

Commit

Permalink
Feat: Vulkan framebuffer resize
Browse files Browse the repository at this point in the history
  • Loading branch information
brenocq committed Dec 11, 2023
1 parent 6ccf0e7 commit 99590da
Show file tree
Hide file tree
Showing 20 changed files with 148 additions and 120 deletions.
2 changes: 2 additions & 0 deletions src/atta/graphics/apis/openGL/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ void Pipeline::begin(std::shared_ptr<RenderQueue> renderQueue) { _shader->bind()

void Pipeline::end() { _shader->unbind(); }

void Pipeline::resize(uint32_t width, uint32_t height) { _renderPass->getFramebuffer()->resize(width, height); }

void* Pipeline::getImGuiTexture() const {
return reinterpret_cast<void*>(std::static_pointer_cast<Image>(_renderPass->getFramebuffer()->getImage(0))->getImGuiImage());
}
Expand Down
2 changes: 2 additions & 0 deletions src/atta/graphics/apis/openGL/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Pipeline final : public gfx::Pipeline {
void begin(std::shared_ptr<RenderQueue> renderQueue) override;
void end() override;

void resize(uint32_t width, uint32_t height) override;

void* getImGuiTexture() const override;
};

Expand Down
39 changes: 24 additions & 15 deletions src/atta/graphics/apis/vulkan/framebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@ namespace atta::graphics::vk {

Framebuffer::Framebuffer(const gfx::Framebuffer::CreateInfo& info)
: gfx::Framebuffer(info), _framebuffer(VK_NULL_HANDLE), _device(common::getDevice()) {
resize(_width, _height);
}

Framebuffer::~Framebuffer() {
if (_framebuffer != VK_NULL_HANDLE)
vkDestroyFramebuffer(_device->getHandle(), _framebuffer, nullptr);
}

void Framebuffer::bind(bool clear) {
if (_framebuffer == VK_NULL_HANDLE) {
LOG_WARN("gfx::vk::Framebuffer", "Trying to bind framebuffer [w]$0[] that was never created", _debugName);
}
}
void Framebuffer::unbind() {}

void Framebuffer::resize(uint32_t width, uint32_t height, bool forceRecreate) {
_width = width;
_height = height;

// Create attachment images
_images.clear();
for (unsigned i = 0; i < _attachments.size(); i++) {
Expand All @@ -29,20 +48,6 @@ Framebuffer::Framebuffer(const gfx::Framebuffer::CreateInfo& info)
}
}

Framebuffer::~Framebuffer() {
if (_framebuffer != VK_NULL_HANDLE)
vkDestroyFramebuffer(_device->getHandle(), _framebuffer, nullptr);
}

void Framebuffer::bind(bool clear) {
if (_framebuffer == VK_NULL_HANDLE) {
LOG_WARN("gfx::vk::Framebuffer", "Trying to bind framebuffer [w]$0[] that was never created", _debugName);
}
}
void Framebuffer::unbind() {}

void Framebuffer::resize(uint32_t width, uint32_t height, bool forceRecreate) {}

int Framebuffer::readPixel(unsigned attachmentIndex, unsigned x, unsigned y) {}
std::vector<uint8_t> Framebuffer::readImage(unsigned attachmentIndex) {}

Expand All @@ -53,6 +58,10 @@ std::shared_ptr<RenderPass> Framebuffer::getRenderPass() const { return _renderP
void Framebuffer::create(std::shared_ptr<RenderPass> renderPass) {
_renderPass = renderPass;

// Destroy framebuffer is necessary
if (_framebuffer != VK_NULL_HANDLE)
vkDestroyFramebuffer(_device->getHandle(), _framebuffer, nullptr);

// Get image views
std::vector<VkImageView> attachments;
for (std::shared_ptr<gfx::Image> image : _images)
Expand All @@ -69,7 +78,7 @@ void Framebuffer::create(std::shared_ptr<RenderPass> renderPass) {
framebufferInfo.layers = 1;

if (vkCreateFramebuffer(_device->getHandle(), &framebufferInfo, nullptr, &_framebuffer) != VK_SUCCESS)
LOG_ERROR("gfx::vk::FrameBuffer", "Failed to create frame buffer!");
LOG_ERROR("gfx::vk::Framebuffer", "Failed to create frame buffer!");
}

} // namespace atta::graphics::vk
8 changes: 5 additions & 3 deletions src/atta/graphics/apis/vulkan/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ namespace atta::graphics::vk {

Image::Image(const gfx::Image::CreateInfo& info)
: gfx::Image(info), _image(VK_NULL_HANDLE), _imageView(VK_NULL_HANDLE), _sampler(VK_NULL_HANDLE), _memory(VK_NULL_HANDLE),
_device(common::getDevice()), _destroyImage(true) {
_imGuiDescriptorSet(VK_NULL_HANDLE), _device(common::getDevice()), _destroyImage(true) {
_format = supportedFormat(_format);
resize(_width, _height, true);
}

Image::Image(const gfx::Image::CreateInfo& info, std::shared_ptr<Device> device, VkImage image)
: gfx::Image(info), _image(image), _imageView(VK_NULL_HANDLE), _sampler(VK_NULL_HANDLE), _memory(VK_NULL_HANDLE), _device(device),
_destroyImage(false) {
: gfx::Image(info), _image(image), _imageView(VK_NULL_HANDLE), _sampler(VK_NULL_HANDLE), _memory(VK_NULL_HANDLE),
_imGuiDescriptorSet(VK_NULL_HANDLE), _device(device), _destroyImage(false) {
_format = supportedFormat(_format);
createImageView();
}
Expand Down Expand Up @@ -277,6 +277,8 @@ void Image::allocMemory() {
}

void Image::destroy() {
if (_imGuiDescriptorSet != VK_NULL_HANDLE)
ImGui_ImplVulkan_RemoveTexture(_imGuiDescriptorSet);
if (_imageView != VK_NULL_HANDLE)
vkDestroyImageView(_device->getHandle(), _imageView, nullptr);
if (_sampler != VK_NULL_HANDLE)
Expand Down
2 changes: 1 addition & 1 deletion src/atta/graphics/apis/vulkan/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ class Image final : public gfx::Image {
VkImage _image;
VkImageView _imageView;
VkSampler _sampler;
VkDescriptorSet _imGuiDescriptorSet; // Used to display images in ImGui;
VkDeviceMemory _memory;
VkImageLayout _layout;
VkDescriptorSet _imGuiDescriptorSet; // Used to display images in ImGui;
std::shared_ptr<Device> _device;

bool _destroyImage;
Expand Down
12 changes: 9 additions & 3 deletions src/atta/graphics/apis/vulkan/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ Pipeline::Pipeline(const gfx::Pipeline::CreateInfo& info) : gfx::Pipeline(info),

if (vkCreateGraphicsPipelines(_device->getHandle(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &_pipeline) != VK_SUCCESS)
LOG_ERROR("gfx::vk::Pipeline", "Failed to create pipeline!");
LOG_DEBUG("Pipeline", "Pipeline created!");
}

Pipeline::~Pipeline() {
Expand All @@ -174,8 +175,8 @@ void Pipeline::begin(std::shared_ptr<gfx::RenderQueue> renderQueue) {
VkViewport viewport{};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = _renderPass->getFramebuffer()->getWidth();
viewport.height = _renderPass->getFramebuffer()->getHeight();
viewport.width = _framebuffers[0]->getWidth();
viewport.height = _framebuffers[0]->getHeight();
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
Expand All @@ -192,6 +193,11 @@ void Pipeline::end() {
_shader->unbind();
}

void Pipeline::resize(uint32_t width, uint32_t height) {
_framebuffers[0]->resize(width, height);
_framebuffers[0]->create(std::dynamic_pointer_cast<vk::RenderPass>(_renderPass));
}

void Pipeline::renderMesh(StringId meshSid) {
std::shared_ptr<vk::Mesh> mesh = std::dynamic_pointer_cast<vk::Mesh>(Manager::getInstance().getMeshes().at(meshSid));
if (mesh) {
Expand All @@ -208,7 +214,7 @@ void Pipeline::renderMesh(StringId meshSid) {
}

void* Pipeline::getImGuiTexture() const {
return reinterpret_cast<void*>(std::static_pointer_cast<Image>(_renderPass->getFramebuffer()->getImage(0))->getImGuiImage());
return reinterpret_cast<void*>(std::static_pointer_cast<Image>(_framebuffers[0]->getImage(0))->getImGuiImage());
}

VkPipeline Pipeline::getHandle() const { return _pipeline; }
Expand Down
2 changes: 2 additions & 0 deletions src/atta/graphics/apis/vulkan/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class Pipeline final : public gfx::Pipeline {
void begin(std::shared_ptr<RenderQueue> renderQueue) override;
void end() override;

void resize(uint32_t width, uint32_t height) override;

void renderMesh(StringId meshSid) override;

void* getImGuiTexture() const override;
Expand Down
18 changes: 9 additions & 9 deletions src/atta/graphics/apis/vulkan/renderPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ void RenderPass::end() {
}

void RenderPass::begin(VkCommandBuffer commandBuffer) {
VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = _renderPass;
renderPassInfo.framebuffer = std::dynamic_pointer_cast<Framebuffer>(_framebuffer)->getHandle();
renderPassInfo.renderArea.offset = {0, 0};
renderPassInfo.renderArea.extent = {_framebuffer->getWidth(), _framebuffer->getHeight()};
VkRenderPassBeginInfo renderPassBeginInfo{};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.renderPass = _renderPass;
renderPassBeginInfo.framebuffer = std::dynamic_pointer_cast<vk::Framebuffer>(_framebuffer)->getHandle();
renderPassBeginInfo.renderArea.offset = {0, 0};
renderPassBeginInfo.renderArea.extent = {_framebuffer->getWidth(), _framebuffer->getHeight()};
// LOG_DEBUG("RenderPass", "Frame buf is $2 -> $0 $1", _framebuffer->getWidth(), _framebuffer->getHeight(), _framebuffer->getDebugName());

std::vector<VkClearValue> clearValues{};
Expand All @@ -124,10 +124,10 @@ void RenderPass::begin(VkCommandBuffer commandBuffer) {
clearValues.push_back(clearDepth);
}
}
renderPassInfo.clearValueCount = clearValues.size();
renderPassInfo.pClearValues = clearValues.data();
renderPassBeginInfo.clearValueCount = clearValues.size();
renderPassBeginInfo.pClearValues = clearValues.data();

vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
}

void RenderPass::end(VkCommandBuffer commandBuffer) { vkCmdEndRenderPass(commandBuffer); }
Expand Down
10 changes: 5 additions & 5 deletions src/atta/graphics/apis/vulkan/renderQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@ RenderQueue::~RenderQueue() {
_commandPool.reset();
}

void RenderQueue::begin() {
_fence->wait();
_fence->reset();
_commandBuffers->begin(0);
}
void RenderQueue::begin() { _commandBuffers->begin(0); }

void RenderQueue::end() {
_commandBuffers->end(0);
Expand All @@ -39,6 +35,10 @@ void RenderQueue::end() {
submitInfo.pCommandBuffers = &cmdBuf;
if (vkQueueSubmit(_device->getGraphicsQueue(), 1, &submitInfo, _fence->getHandle()) != VK_SUCCESS)
LOG_ERROR("gfx::vk::RenderQueue", "Failed to submit render queue!");

// Wait commands to complete
_fence->wait();
_fence->reset();
}

VkCommandBuffer RenderQueue::getCommandBuffer() { return _commandBuffers->getHandles()[0]; }
Expand Down
108 changes: 54 additions & 54 deletions src/atta/graphics/cameras/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ void Camera::update() {

void Camera::move() {
switch (_control) {
case Control::PLANAR:
movePlanar();
break;
case Control::FIRST_PERSON:
moveFirstPerson();
break;
default:
break;
case Control::PLANAR:
movePlanar();
break;
case Control::FIRST_PERSON:
moveFirstPerson();
break;
default:
break;
}
}

void Camera::movePlanar() {
if (!ImGui::IsMouseDown(2)) // Move only if middle button is pressed
if (!ImGui::IsMouseDown(ImGuiMouseButton_Middle)) // Move only if middle button is pressed
return;

ImGuiIO& io = ImGui::GetIO();
Expand All @@ -44,7 +44,7 @@ void Camera::movePlanar() {
}

void Camera::moveFirstPerson() {
if (!ImGui::IsMouseDown(2)) // Move only if middle button is pressed
if (!ImGui::IsMouseDown(ImGuiMouseButton_Middle)) // Move only if middle button is pressed
return;

static float lastTimeFront = 0;
Expand All @@ -63,71 +63,71 @@ void Camera::moveFirstPerson() {
_up = vec3(0, 0, 1);

// Move front/back
if (ImGui::IsKeyDown('W') || ImGui::IsKeyDown('S')) {
if (ImGui::IsKeyDown(ImGuiKey_W) || ImGui::IsKeyDown(ImGuiKey_S)) {
int key = 0;

if (ImGui::GetKeyData('W')->DownDuration > 0 && ImGui::GetKeyData('S')->DownDuration > 0)
if (ImGui::GetKeyData('W')->DownDuration < ImGui::GetKeyData('S')->DownDuration)
key = 'W';
if (io.KeysData[ImGuiKey_W].DownDuration > 0 && io.KeysData[ImGuiKey_S].DownDuration > 0)
if (io.KeysData[ImGuiKey_W].DownDuration < io.KeysData[ImGuiKey_S].DownDuration)
key = ImGuiKey_W;
else
key = 'S';
else if (ImGui::GetKeyData('W')->DownDuration > 0)
key = 'W';
else if (ImGui::GetKeyData('S')->DownDuration > 0)
key = 'S';
key = ImGuiKey_S;
else if (io.KeysData[ImGuiKey_W].DownDuration > 0)
key = ImGuiKey_W;
else if (io.KeysData[ImGuiKey_S].DownDuration > 0)
key = ImGuiKey_S;

if (key) {
if (ImGui::GetKeyData(key)->DownDuration < lastTimeFront)
if (io.KeysData[key].DownDuration < lastTimeFront)
lastTimeFront = 0;

float delta = (ImGui::GetKeyData(key)->DownDuration - lastTimeFront) * (key == 'W' ? 1 : -1) * _speed;
lastTimeFront = ImGui::GetKeyData(key)->DownDuration;
float delta = (io.KeysData[key].DownDuration - lastTimeFront) * (key == ImGuiKey_W ? 1 : -1) * _speed;
lastTimeFront = io.KeysData[key].DownDuration;
_position += _front * delta;
}
}

// Move left/right
if (ImGui::IsKeyDown('A') || ImGui::IsKeyDown('D')) {
if (ImGui::IsKeyDown(ImGuiKey_A) || ImGui::IsKeyDown(ImGuiKey_D)) {
int key = 0;
if (ImGui::GetKeyData('A')->DownDuration > 0 && ImGui::GetKeyData('D')->DownDuration > 0)
if (ImGui::GetKeyData('A')->DownDuration < ImGui::GetKeyData('D')->DownDuration)
key = 'A';
if (io.KeysData[ImGuiKey_A].DownDuration > 0 && io.KeysData[ImGuiKey_D].DownDuration > 0)
if (io.KeysData[ImGuiKey_A].DownDuration < io.KeysData[ImGuiKey_D].DownDuration)
key = ImGuiKey_A;
else
key = 'D';
else if (ImGui::GetKeyData('A')->DownDuration > 0)
key = 'A';
else if (ImGui::GetKeyData('D')->DownDuration > 0)
key = 'D';
key = ImGuiKey_D;
else if (io.KeysData[ImGuiKey_A].DownDuration > 0)
key = ImGuiKey_A;
else if (io.KeysData[ImGuiKey_D].DownDuration > 0)
key = ImGuiKey_D;

if (key) {
if (ImGui::GetKeyData(key)->DownDuration < lastTimeLeft)
if (io.KeysData[key].DownDuration < lastTimeLeft)
lastTimeLeft = 0;

float delta = (ImGui::GetKeyData(key)->DownDuration - lastTimeLeft) * (key == 'A' ? 1 : -1) * _speed;
lastTimeLeft = ImGui::GetKeyData(key)->DownDuration;
float delta = (io.KeysData[key].DownDuration - lastTimeLeft) * (key == ImGuiKey_A ? 1 : -1) * _speed;
lastTimeLeft = io.KeysData[key].DownDuration;
_position += _left * delta;
}
}

// Move up/down
if (ImGui::IsKeyDown('E') || ImGui::IsKeyDown('Q')) {
if (ImGui::IsKeyDown(ImGuiKey_E) || ImGui::IsKeyDown(ImGuiKey_Q)) {
int key = 0;
if (ImGui::GetKeyData('E')->DownDuration > 0 && ImGui::GetKeyData('Q')->DownDuration > 0)
if (ImGui::GetKeyData('E')->DownDuration < ImGui::GetKeyData('Q')->DownDuration)
key = 'E';
if (io.KeysData[ImGuiKey_E].DownDuration > 0 && io.KeysData[ImGuiKey_Q].DownDuration > 0)
if (io.KeysData[ImGuiKey_E].DownDuration < io.KeysData[ImGuiKey_Q].DownDuration)
key = ImGuiKey_E;
else
key = 'Q';
else if (ImGui::GetKeyData('E')->DownDuration > 0)
key = 'E';
else if (ImGui::GetKeyData('Q')->DownDuration > 0)
key = 'Q';
key = ImGuiKey_Q;
else if (io.KeysData[ImGuiKey_E].DownDuration > 0)
key = ImGuiKey_E;
else if (io.KeysData[ImGuiKey_Q].DownDuration > 0)
key = ImGuiKey_Q;

if (key) {
if (ImGui::GetKeyData(key)->DownDuration < lastTimeUp)
if (io.KeysData[key].DownDuration < lastTimeUp)
lastTimeUp = 0;

float delta = (ImGui::GetKeyData(key)->DownDuration - lastTimeUp) * (key == 'E' ? 1 : -1) * _speed;
lastTimeUp = ImGui::GetKeyData(key)->DownDuration;
float delta = (io.KeysData[key].DownDuration - lastTimeUp) * (key == ImGuiKey_E ? 1 : -1) * _speed;
lastTimeUp = io.KeysData[key].DownDuration;
_position += _up * delta;
}
}
Expand All @@ -146,14 +146,14 @@ void Camera::renderUI() {
for (size_t j = 0; j < controls.size(); j++) {
if (ImGui::Selectable(controls[j], comboValue == j)) {
switch (j) {
case 0:
if (comboValue != 0)
_control = Control::PLANAR;
break;
case 1:
if (comboValue != 1)
_control = Control::FIRST_PERSON;
break;
case 0:
if (comboValue != 0)
_control = Control::PLANAR;
break;
case 1:
if (comboValue != 1)
_control = Control::FIRST_PERSON;
break;
}
}
if (comboValue == j)
Expand Down
Loading

0 comments on commit 99590da

Please sign in to comment.