Add moving camera
This commit is contained in:
parent
82ede190a6
commit
dd8131a059
6 changed files with 82 additions and 63 deletions
8
include/camera.h
Normal file
8
include/camera.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Camera {
|
||||||
|
public:
|
||||||
|
glm::vec3 position, target;
|
||||||
|
};
|
|
@ -19,11 +19,11 @@ struct RenderTarget {
|
||||||
VkImage* offscreenColorImages = nullptr;
|
VkImage* offscreenColorImages = nullptr;
|
||||||
VkDeviceMemory* offscreenColorMemory = nullptr;
|
VkDeviceMemory* offscreenColorMemory = nullptr;
|
||||||
VkImageView* offscreenColorImageViews = nullptr;
|
VkImageView* offscreenColorImageViews = nullptr;
|
||||||
|
|
||||||
VkImage* offscreenDepthImages = nullptr;
|
VkImage* offscreenDepthImages = nullptr;
|
||||||
VkDeviceMemory* offscreenDepthMemory = nullptr;
|
VkDeviceMemory* offscreenDepthMemory = nullptr;
|
||||||
VkImageView* offscreenDepthImageViews = nullptr;
|
VkImageView* offscreenDepthImageViews = nullptr;
|
||||||
|
|
||||||
VkFramebuffer* offscreenFramebuffers = nullptr;
|
VkFramebuffer* offscreenFramebuffers = nullptr;
|
||||||
|
|
||||||
VkCommandBuffer* commandBuffers = nullptr;
|
VkCommandBuffer* commandBuffers = nullptr;
|
||||||
|
@ -37,17 +37,18 @@ struct RenderTarget {
|
||||||
|
|
||||||
class World;
|
class World;
|
||||||
class Mesh;
|
class Mesh;
|
||||||
|
class Camera;
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
void render(World& world, RenderTarget* target);
|
void render(World& world, Camera& camera, RenderTarget* target);
|
||||||
|
|
||||||
RenderTarget* createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTarget* oldRenderTarget = nullptr);
|
RenderTarget* createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTarget* oldRenderTarget = nullptr);
|
||||||
void destroyRenderTarget(RenderTarget* target);
|
void destroyRenderTarget(RenderTarget* target);
|
||||||
|
|
||||||
void takeScreenshot(RenderTarget* target);
|
void takeScreenshot(RenderTarget* target);
|
||||||
|
|
||||||
VkShaderModule createShader(const char* path);
|
VkShaderModule createShader(const char* path);
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
class Renderer;
|
class Renderer;
|
||||||
class World;
|
class World;
|
||||||
struct RenderTarget;
|
struct RenderTarget;
|
||||||
|
class Camera;
|
||||||
|
|
||||||
class WorldPass {
|
class WorldPass {
|
||||||
public:
|
public:
|
||||||
WorldPass(Renderer& renderer);
|
WorldPass(Renderer& renderer);
|
||||||
~WorldPass();
|
~WorldPass();
|
||||||
|
|
||||||
void render(VkCommandBuffer commandBuffer, World& world, RenderTarget* target);
|
void render(VkCommandBuffer commandBuffer, World& world, Camera& camera, RenderTarget* target);
|
||||||
|
|
||||||
VkRenderPass getRenderPass() const {
|
VkRenderPass getRenderPass() const {
|
||||||
return renderPass_;
|
return renderPass_;
|
||||||
|
@ -23,17 +24,17 @@ private:
|
||||||
void createPipeline();
|
void createPipeline();
|
||||||
void createUniformBuffer();
|
void createUniformBuffer();
|
||||||
void createDescriptorSet();
|
void createDescriptorSet();
|
||||||
|
|
||||||
VkRenderPass renderPass_ = nullptr;
|
VkRenderPass renderPass_ = nullptr;
|
||||||
|
|
||||||
VkDescriptorSetLayout setLayout_ = nullptr;
|
VkDescriptorSetLayout setLayout_ = nullptr;
|
||||||
|
|
||||||
VkPipelineLayout pipelineLayout_ = nullptr;
|
VkPipelineLayout pipelineLayout_ = nullptr;
|
||||||
VkPipeline pipeline_ = nullptr;
|
VkPipeline pipeline_ = nullptr;
|
||||||
|
|
||||||
VkDeviceMemory lightMemory_ = nullptr;
|
VkDeviceMemory lightMemory_ = nullptr;
|
||||||
VkBuffer lightBuffer_ = nullptr;
|
VkBuffer lightBuffer_ = nullptr;
|
||||||
|
|
||||||
VkDescriptorSet descriptorSet_ = nullptr;
|
VkDescriptorSet descriptorSet_ = nullptr;
|
||||||
|
|
||||||
Renderer& renderer_;
|
Renderer& renderer_;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
SDL_Window* window = nullptr;
|
SDL_Window* window = nullptr;
|
||||||
|
|
||||||
|
@ -145,6 +146,10 @@ int main(int, char*[]) {
|
||||||
|
|
||||||
world.lights.push_back(light);
|
world.lights.push_back(light);
|
||||||
|
|
||||||
|
Camera camera;
|
||||||
|
camera.position.y = 1;
|
||||||
|
camera.position.z = 3;
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
while(running) {
|
while(running) {
|
||||||
SDL_Event event = {};
|
SDL_Event event = {};
|
||||||
|
@ -174,7 +179,9 @@ int main(int, char*[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->render(world, target);
|
camera.position.x = sin(platform::getTime() / 500.0f);
|
||||||
|
|
||||||
|
renderer->render(world, camera, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete light;
|
delete light;
|
||||||
|
|
101
src/renderer.cpp
101
src/renderer.cpp
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
Renderer::Renderer() {
|
Renderer::Renderer() {
|
||||||
createInstance();
|
createInstance();
|
||||||
|
@ -47,12 +48,12 @@ Renderer::~Renderer() {
|
||||||
vkDestroyInstance(instance_, nullptr);
|
vkDestroyInstance(instance_, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::render(World& world, RenderTarget* target) {
|
void Renderer::render(World& world, Camera& camera, RenderTarget* target) {
|
||||||
vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &target->currentImage);
|
vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &target->currentImage);
|
||||||
|
|
||||||
vkWaitForFences(device_, 1, &target->fences[target->currentImage], true, UINT64_MAX);
|
vkWaitForFences(device_, 1, &target->fences[target->currentImage], true, UINT64_MAX);
|
||||||
vkResetFences(device_, 1, &target->fences[target->currentImage]);
|
vkResetFences(device_, 1, &target->fences[target->currentImage]);
|
||||||
|
|
||||||
const VkCommandBuffer commandBuffer = target->commandBuffers[target->currentImage];
|
const VkCommandBuffer commandBuffer = target->commandBuffers[target->currentImage];
|
||||||
|
|
||||||
VkCommandBufferBeginInfo beginInfo = {};
|
VkCommandBufferBeginInfo beginInfo = {};
|
||||||
|
@ -72,7 +73,7 @@ void Renderer::render(World& world, RenderTarget* target) {
|
||||||
|
|
||||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||||
|
|
||||||
worldPass_->render(commandBuffer, world, target);
|
worldPass_->render(commandBuffer, world, camera, target);
|
||||||
|
|
||||||
VkClearValue clearColor = {};
|
VkClearValue clearColor = {};
|
||||||
|
|
||||||
|
@ -258,7 +259,7 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
||||||
|
|
||||||
vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenColorImageViews[i]);
|
vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenColorImageViews[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// offscreen depth image
|
// offscreen depth image
|
||||||
{
|
{
|
||||||
VkImageCreateInfo imageCreateInfo = {};
|
VkImageCreateInfo imageCreateInfo = {};
|
||||||
|
@ -273,21 +274,21 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
||||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||||
|
|
||||||
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->offscreenDepthImages[i]);
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->offscreenDepthImages[i]);
|
||||||
|
|
||||||
VkMemoryRequirements memoryRequirements = {};
|
VkMemoryRequirements memoryRequirements = {};
|
||||||
vkGetImageMemoryRequirements(device_, target->offscreenDepthImages[i], &memoryRequirements);
|
vkGetImageMemoryRequirements(device_, target->offscreenDepthImages[i], &memoryRequirements);
|
||||||
|
|
||||||
VkMemoryAllocateInfo allocateInfo = {};
|
VkMemoryAllocateInfo allocateInfo = {};
|
||||||
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
allocateInfo.allocationSize = memoryRequirements.size;
|
allocateInfo.allocationSize = memoryRequirements.size;
|
||||||
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->offscreenDepthMemory[i]);
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->offscreenDepthMemory[i]);
|
||||||
vkBindImageMemory(device_, target->offscreenDepthImages[i], target->offscreenDepthMemory[i], 0);
|
vkBindImageMemory(device_, target->offscreenDepthImages[i], target->offscreenDepthMemory[i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// offscreen depth image view
|
// offscreen depth image view
|
||||||
{
|
{
|
||||||
VkImageViewCreateInfo createInfo = {};
|
VkImageViewCreateInfo createInfo = {};
|
||||||
|
@ -298,7 +299,7 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
||||||
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
createInfo.subresourceRange.levelCount = 1;
|
createInfo.subresourceRange.levelCount = 1;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenDepthImageViews[i]);
|
vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenDepthImageViews[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +309,7 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
||||||
target->offscreenColorImageViews[i],
|
target->offscreenColorImageViews[i],
|
||||||
target->offscreenDepthImageViews[i]
|
target->offscreenDepthImageViews[i]
|
||||||
};
|
};
|
||||||
|
|
||||||
VkFramebufferCreateInfo framebufferInfo = {};
|
VkFramebufferCreateInfo framebufferInfo = {};
|
||||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
framebufferInfo.renderPass = worldPass_->getRenderPass();
|
framebufferInfo.renderPass = worldPass_->getRenderPass();
|
||||||
|
@ -371,11 +372,11 @@ void Renderer::destroyRenderTarget(RenderTarget* target) {
|
||||||
|
|
||||||
for(uint32_t i = 0; i < target->numImages; i++) {
|
for(uint32_t i = 0; i < target->numImages; i++) {
|
||||||
vkDestroyFramebuffer(device_, target->offscreenFramebuffers[i], nullptr);
|
vkDestroyFramebuffer(device_, target->offscreenFramebuffers[i], nullptr);
|
||||||
|
|
||||||
vkDestroyImageView(device_, target->offscreenDepthImageViews[i], nullptr);
|
vkDestroyImageView(device_, target->offscreenDepthImageViews[i], nullptr);
|
||||||
vkFreeMemory(device_, target->offscreenDepthMemory[i], nullptr);
|
vkFreeMemory(device_, target->offscreenDepthMemory[i], nullptr);
|
||||||
vkDestroyImage(device_, target->offscreenDepthImages[i], nullptr);
|
vkDestroyImage(device_, target->offscreenDepthImages[i], nullptr);
|
||||||
|
|
||||||
vkDestroyImageView(device_, target->offscreenColorImageViews[i], nullptr);
|
vkDestroyImageView(device_, target->offscreenColorImageViews[i], nullptr);
|
||||||
vkFreeMemory(device_, target->offscreenColorMemory[i], nullptr);
|
vkFreeMemory(device_, target->offscreenColorMemory[i], nullptr);
|
||||||
vkDestroyImage(device_, target->offscreenColorImages[i], nullptr);
|
vkDestroyImage(device_, target->offscreenColorImages[i], nullptr);
|
||||||
|
@ -383,7 +384,7 @@ void Renderer::destroyRenderTarget(RenderTarget* target) {
|
||||||
vkDestroyFramebuffer(device_, target->swapchainFramebuffers[i], nullptr);
|
vkDestroyFramebuffer(device_, target->swapchainFramebuffers[i], nullptr);
|
||||||
vkDestroyImageView(device_, target->swapchainImageViews[i], nullptr);
|
vkDestroyImageView(device_, target->swapchainImageViews[i], nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] target->offscreenFramebuffers;
|
delete[] target->offscreenFramebuffers;
|
||||||
delete[] target->offscreenDepthImageViews;
|
delete[] target->offscreenDepthImageViews;
|
||||||
delete[] target->offscreenDepthMemory;
|
delete[] target->offscreenDepthMemory;
|
||||||
|
@ -395,7 +396,7 @@ void Renderer::destroyRenderTarget(RenderTarget* target) {
|
||||||
delete[] target->swapchainFramebuffers;
|
delete[] target->swapchainFramebuffers;
|
||||||
delete[] target->swapchainImageViews;
|
delete[] target->swapchainImageViews;
|
||||||
delete[] target->swapchainImages;
|
delete[] target->swapchainImages;
|
||||||
|
|
||||||
delete[] target->postSets;
|
delete[] target->postSets;
|
||||||
|
|
||||||
vkDestroySwapchainKHR(device_, target->swapchain, nullptr);
|
vkDestroySwapchainKHR(device_, target->swapchain, nullptr);
|
||||||
|
@ -416,35 +417,35 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
||||||
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||||
|
|
||||||
VkImage image = nullptr;
|
VkImage image = nullptr;
|
||||||
vkCreateImage(device_, &imageCreateInfo, nullptr, &image);
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &image);
|
||||||
|
|
||||||
VkMemoryRequirements memoryRequirements = {};
|
VkMemoryRequirements memoryRequirements = {};
|
||||||
vkGetImageMemoryRequirements(device_, image, &memoryRequirements);
|
vkGetImageMemoryRequirements(device_, image, &memoryRequirements);
|
||||||
|
|
||||||
VkMemoryAllocateInfo allocateInfo = {};
|
VkMemoryAllocateInfo allocateInfo = {};
|
||||||
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
allocateInfo.allocationSize = memoryRequirements.size;
|
allocateInfo.allocationSize = memoryRequirements.size;
|
||||||
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||||
|
|
||||||
VkDeviceMemory imageMemory = nullptr;
|
VkDeviceMemory imageMemory = nullptr;
|
||||||
vkAllocateMemory(device_, &allocateInfo, nullptr, &imageMemory);
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &imageMemory);
|
||||||
vkBindImageMemory(device_, image, imageMemory, 0);
|
vkBindImageMemory(device_, image, imageMemory, 0);
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo bufferAllocateInfo = {};
|
VkCommandBufferAllocateInfo bufferAllocateInfo = {};
|
||||||
bufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
bufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
bufferAllocateInfo.commandPool = commandPool_;
|
bufferAllocateInfo.commandPool = commandPool_;
|
||||||
bufferAllocateInfo.commandBufferCount = 1;
|
bufferAllocateInfo.commandBufferCount = 1;
|
||||||
|
|
||||||
VkCommandBuffer commandBuffer = nullptr;
|
VkCommandBuffer commandBuffer = nullptr;
|
||||||
vkAllocateCommandBuffers(device_, &bufferAllocateInfo, &commandBuffer);
|
vkAllocateCommandBuffers(device_, &bufferAllocateInfo, &commandBuffer);
|
||||||
|
|
||||||
VkCommandBufferBeginInfo beginInfo = {};
|
VkCommandBufferBeginInfo beginInfo = {};
|
||||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
|
||||||
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
||||||
|
|
||||||
// change screenshot image to transfer dst layout
|
// change screenshot image to transfer dst layout
|
||||||
{
|
{
|
||||||
VkImageMemoryBarrier imageMemoryBarrier = {};
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
||||||
|
@ -455,7 +456,7 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
||||||
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
||||||
|
|
||||||
vkCmdPipelineBarrier(
|
vkCmdPipelineBarrier(
|
||||||
commandBuffer,
|
commandBuffer,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
@ -465,9 +466,9 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
0, nullptr,
|
0, nullptr,
|
||||||
1, &imageMemoryBarrier);
|
1, &imageMemoryBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
const VkImage srcImage = target->swapchainImages[0]; // FIXME: use previous image
|
const VkImage srcImage = target->swapchainImages[0]; // FIXME: use previous image
|
||||||
|
|
||||||
// change offscreen image to transfer src layout
|
// change offscreen image to transfer src layout
|
||||||
{
|
{
|
||||||
VkImageMemoryBarrier imageMemoryBarrier = {};
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
||||||
|
@ -480,7 +481,7 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
||||||
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
||||||
|
|
||||||
vkCmdPipelineBarrier(
|
vkCmdPipelineBarrier(
|
||||||
commandBuffer,
|
commandBuffer,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
@ -490,7 +491,7 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
0, nullptr,
|
0, nullptr,
|
||||||
1, &imageMemoryBarrier);
|
1, &imageMemoryBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageCopy imageCopy = {};
|
VkImageCopy imageCopy = {};
|
||||||
imageCopy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
imageCopy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
imageCopy.srcSubresource.layerCount = 1;
|
imageCopy.srcSubresource.layerCount = 1;
|
||||||
|
@ -499,7 +500,7 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
imageCopy.extent.width = target->extent.width;
|
imageCopy.extent.width = target->extent.width;
|
||||||
imageCopy.extent.height = target->extent.height;
|
imageCopy.extent.height = target->extent.height;
|
||||||
imageCopy.extent.depth = 1;
|
imageCopy.extent.depth = 1;
|
||||||
|
|
||||||
// Issue the copy command
|
// Issue the copy command
|
||||||
vkCmdCopyImage(
|
vkCmdCopyImage(
|
||||||
commandBuffer,
|
commandBuffer,
|
||||||
|
@ -509,7 +510,7 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
1,
|
1,
|
||||||
&imageCopy);
|
&imageCopy);
|
||||||
|
|
||||||
// change screenshot image from transfer dst to general (for mapping memory)
|
// change screenshot image from transfer dst to general (for mapping memory)
|
||||||
{
|
{
|
||||||
VkImageMemoryBarrier imageMemoryBarrier = {};
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
||||||
|
@ -522,7 +523,7 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
||||||
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
||||||
|
|
||||||
vkCmdPipelineBarrier(
|
vkCmdPipelineBarrier(
|
||||||
commandBuffer,
|
commandBuffer,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
@ -532,7 +533,7 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
0, nullptr,
|
0, nullptr,
|
||||||
1, &imageMemoryBarrier);
|
1, &imageMemoryBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// change offscreen image layout back to normal
|
// change offscreen image layout back to normal
|
||||||
{
|
{
|
||||||
VkImageMemoryBarrier imageMemoryBarrier = {};
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
||||||
|
@ -545,7 +546,7 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
||||||
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
||||||
|
|
||||||
vkCmdPipelineBarrier(
|
vkCmdPipelineBarrier(
|
||||||
commandBuffer,
|
commandBuffer,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
@ -555,54 +556,54 @@ void Renderer::takeScreenshot(RenderTarget* target) {
|
||||||
0, nullptr,
|
0, nullptr,
|
||||||
1, &imageMemoryBarrier);
|
1, &imageMemoryBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkEndCommandBuffer(commandBuffer);
|
vkEndCommandBuffer(commandBuffer);
|
||||||
|
|
||||||
VkSubmitInfo submitInfo = {};
|
VkSubmitInfo submitInfo = {};
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
submitInfo.commandBufferCount = 1;
|
submitInfo.commandBufferCount = 1;
|
||||||
submitInfo.pCommandBuffers = &commandBuffer;
|
submitInfo.pCommandBuffers = &commandBuffer;
|
||||||
|
|
||||||
VkFenceCreateInfo fenceCreateInfo = {};
|
VkFenceCreateInfo fenceCreateInfo = {};
|
||||||
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
|
|
||||||
VkFence fence = nullptr;
|
VkFence fence = nullptr;
|
||||||
vkCreateFence(device_, &fenceCreateInfo, nullptr, &fence);
|
vkCreateFence(device_, &fenceCreateInfo, nullptr, &fence);
|
||||||
|
|
||||||
vkQueueSubmit(graphicsQueue_, 1, &submitInfo, fence);
|
vkQueueSubmit(graphicsQueue_, 1, &submitInfo, fence);
|
||||||
|
|
||||||
vkWaitForFences(device_, 1, &fence, true, -1);
|
vkWaitForFences(device_, 1, &fence, true, -1);
|
||||||
vkDestroyFence(device_, fence, nullptr);
|
vkDestroyFence(device_, fence, nullptr);
|
||||||
|
|
||||||
vkFreeCommandBuffers(device_, commandPool_, 1, &commandBuffer);
|
vkFreeCommandBuffers(device_, commandPool_, 1, &commandBuffer);
|
||||||
|
|
||||||
VkImageSubresource subResource = {};
|
VkImageSubresource subResource = {};
|
||||||
subResource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
subResource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
|
||||||
VkSubresourceLayout subResourceLayout = {};
|
VkSubresourceLayout subResourceLayout = {};
|
||||||
vkGetImageSubresourceLayout(device_, image, &subResource, &subResourceLayout);
|
vkGetImageSubresourceLayout(device_, image, &subResource, &subResourceLayout);
|
||||||
|
|
||||||
const char* data = nullptr;
|
const char* data = nullptr;
|
||||||
vkMapMemory(device_, imageMemory, 0, VK_WHOLE_SIZE, 0, (void**)&data);
|
vkMapMemory(device_, imageMemory, 0, VK_WHOLE_SIZE, 0, (void**)&data);
|
||||||
data += subResourceLayout.offset;
|
data += subResourceLayout.offset;
|
||||||
|
|
||||||
std::ofstream file("screenshot.ppm", std::ios::out | std::ios::binary);
|
std::ofstream file("screenshot.ppm", std::ios::out | std::ios::binary);
|
||||||
file << "P6\n" << target->extent.width << "\n" << target->extent.height << "\n" << 255 << "\n";
|
file << "P6\n" << target->extent.width << "\n" << target->extent.height << "\n" << 255 << "\n";
|
||||||
|
|
||||||
for(uint32_t y = 0; y < target->extent.height; y++) {
|
for(uint32_t y = 0; y < target->extent.height; y++) {
|
||||||
const unsigned int* row = reinterpret_cast<const unsigned int*>(data);
|
const unsigned int* row = reinterpret_cast<const unsigned int*>(data);
|
||||||
for(uint32_t x = 0; x < target->extent.width; x++) {
|
for(uint32_t x = 0; x < target->extent.width; x++) {
|
||||||
file.write(reinterpret_cast<const char*>(row), 3);
|
file.write(reinterpret_cast<const char*>(row), 3);
|
||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
|
|
||||||
data += subResourceLayout.rowPitch;
|
data += subResourceLayout.rowPitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
vkUnmapMemory(device_, imageMemory);
|
vkUnmapMemory(device_, imageMemory);
|
||||||
|
|
||||||
vkFreeMemory(device_, imageMemory, nullptr);
|
vkFreeMemory(device_, imageMemory, nullptr);
|
||||||
vkDestroyImage(device_, image, nullptr);
|
vkDestroyImage(device_, image, nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
WorldPass::WorldPass(Renderer& renderer) : renderer_(renderer) {
|
WorldPass::WorldPass(Renderer& renderer) : renderer_(renderer) {
|
||||||
createRenderPass();
|
createRenderPass();
|
||||||
|
@ -28,7 +29,7 @@ WorldPass::~WorldPass() {
|
||||||
vkDestroyBuffer(renderer_.getDevice(), lightBuffer_, nullptr);
|
vkDestroyBuffer(renderer_.getDevice(), lightBuffer_, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldPass::render(VkCommandBuffer commandBuffer, World& world, RenderTarget* target) {
|
void WorldPass::render(VkCommandBuffer commandBuffer, World& world, Camera& camera, RenderTarget* target) {
|
||||||
struct ShaderLight {
|
struct ShaderLight {
|
||||||
glm::vec4 position;
|
glm::vec4 position;
|
||||||
glm::vec3 color;
|
glm::vec3 color;
|
||||||
|
@ -65,7 +66,7 @@ void WorldPass::render(VkCommandBuffer commandBuffer, World& world, RenderTarget
|
||||||
for(const auto& mesh : world.meshes) {
|
for(const auto& mesh : world.meshes) {
|
||||||
glm::mat4 mvp;
|
glm::mat4 mvp;
|
||||||
mvp = glm::perspective(glm::radians(75.0f), (float)target->extent.width / target->extent.height, 0.1f, 100.0f);
|
mvp = glm::perspective(glm::radians(75.0f), (float)target->extent.width / target->extent.height, 0.1f, 100.0f);
|
||||||
mvp *= glm::lookAt(glm::vec3(2), glm::vec3(0), glm::vec3(0, -1, 0));
|
mvp *= glm::lookAt(camera.position, camera.target, glm::vec3(0, -1, 0));
|
||||||
|
|
||||||
vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &mvp);
|
vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &mvp);
|
||||||
|
|
||||||
|
|
Reference in a new issue