Archived
1
Fork 0

Add moving camera

This commit is contained in:
Joshua Goins 2018-10-25 08:57:36 -04:00
parent 82ede190a6
commit dd8131a059
6 changed files with 82 additions and 63 deletions

8
include/camera.h Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#include <glm/glm.hpp>
class Camera {
public:
glm::vec3 position, target;
};

View file

@ -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);

View file

@ -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_;

View file

@ -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;

View file

@ -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);
} }

View file

@ -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);