Archived
1
Fork 0

Add material class

This commit is contained in:
Joshua Goins 2018-11-06 09:08:55 -05:00
parent b53e2bb9ce
commit 0c970b0236
12 changed files with 4643 additions and 2363 deletions

View file

@ -75,4 +75,5 @@ add_data(Graph
data/suzanne.obj data/suzanne.obj
data/test.cim data/test.cim
data/bokeh.png data/bokeh.png
data/scene.obj) data/scene.obj
data/tile.jpg)

12
data/scene.mtl Normal file
View file

@ -0,0 +1,12 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

File diff suppressed because it is too large Load diff

BIN
data/tile.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

16
include/material.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include <vulkan/vulkan.h>
#include <glm/glm.hpp>
class Material {
public:
std::string albedoTexturePath;
VkImage albedoImage = nullptr;
VkDeviceMemory albedoMemory = nullptr;
VkImageView albedoImageView = nullptr;
VkSampler albedoSampler = nullptr;
VkDescriptorSet set = nullptr;
};

View file

@ -6,8 +6,11 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
class Material;
struct Vertex { struct Vertex {
glm::vec3 position, normal; glm::vec3 position, normal;
glm::vec2 uv;
}; };
class Mesh { class Mesh {
@ -15,6 +18,8 @@ public:
std::string name; std::string name;
glm::vec3 position; glm::vec3 position;
Material* material = nullptr;
std::vector<Vertex> vertices; std::vector<Vertex> vertices;
std::vector<uint32_t> indices; std::vector<uint32_t> indices;

View file

@ -32,19 +32,19 @@ struct RenderTarget {
VkImageView* offscreenDepthImageViews = nullptr; VkImageView* offscreenDepthImageViews = nullptr;
VkFramebuffer* offscreenFramebuffers = nullptr; VkFramebuffer* offscreenFramebuffers = nullptr;
// near field // near field
VkImage* nearFieldImages = nullptr; VkImage* nearFieldImages = nullptr;
VkDeviceMemory* nearFieldMemory = nullptr; VkDeviceMemory* nearFieldMemory = nullptr;
VkImageView* nearFieldImageViews = nullptr; VkImageView* nearFieldImageViews = nullptr;
VkFramebuffer* nearFieldFramebuffers = nullptr; VkFramebuffer* nearFieldFramebuffers = nullptr;
// far field // far field
VkImage* farFieldImages = nullptr; VkImage* farFieldImages = nullptr;
VkDeviceMemory* farFieldMemory = nullptr; VkDeviceMemory* farFieldMemory = nullptr;
VkImageView* farFieldImageViews = nullptr; VkImageView* farFieldImageViews = nullptr;
VkFramebuffer* farFieldFramebuffers = nullptr; VkFramebuffer* farFieldFramebuffers = nullptr;
VkCommandBuffer* commandBuffers = nullptr; VkCommandBuffer* commandBuffers = nullptr;
@ -52,12 +52,12 @@ struct RenderTarget {
VkSemaphore imageAvailableSemaphore = nullptr; VkSemaphore imageAvailableSemaphore = nullptr;
VkSemaphore renderFinishedSemaphore = nullptr; VkSemaphore renderFinishedSemaphore = nullptr;
VkFence* fences = nullptr; VkFence* fences = nullptr;
// imgui // imgui
VkBuffer* imguiVertexBuffers = nullptr; VkBuffer* imguiVertexBuffers = nullptr;
VkDeviceMemory* imguiVertexMemorys = nullptr; VkDeviceMemory* imguiVertexMemorys = nullptr;
size_t* imguiVertexBufferSizes = nullptr; size_t* imguiVertexBufferSizes = nullptr;
VkBuffer* imguiIndexBuffers = nullptr; VkBuffer* imguiIndexBuffers = nullptr;
VkDeviceMemory* imguiIndexMemorys = nullptr; VkDeviceMemory* imguiIndexMemorys = nullptr;
size_t* imguiIndexBufferSizes = nullptr; size_t* imguiIndexBufferSizes = nullptr;
@ -69,6 +69,7 @@ struct RenderTarget {
class World; class World;
class Mesh; class Mesh;
class Camera; class Camera;
class Material;
class Renderer { class Renderer {
public: public:
@ -85,12 +86,15 @@ public:
VkShaderModule createShader(const char* path); VkShaderModule createShader(const char* path);
void uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src); void uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src);
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
void fillMeshBuffers(Mesh* mesh); void fillMeshBuffers(Mesh* mesh);
void destroyMeshBuffers(Mesh* mesh); void destroyMeshBuffers(Mesh* mesh);
void fillMaterialBuffers(Material* material);
void destroyMaterialBuffers(Material* material);
VkInstance getInstance() const { VkInstance getInstance() const {
return instance_; return instance_;
} }
@ -98,11 +102,11 @@ public:
VkDevice getDevice() const { VkDevice getDevice() const {
return device_; return device_;
} }
VkQueue getGraphicsQueue() const { VkQueue getGraphicsQueue() const {
return graphicsQueue_; return graphicsQueue_;
} }
VkCommandPool getCommandPool() const { VkCommandPool getCommandPool() const {
return commandPool_; return commandPool_;
} }
@ -115,6 +119,10 @@ public:
return descriptorPool_; return descriptorPool_;
} }
VkDescriptorSetLayout getMaterialSetLayout() const {
return materialSetLayout_;
}
private: private:
void createInstance(); void createInstance();
#ifdef DEBUG #ifdef DEBUG
@ -124,6 +132,7 @@ private:
void createCommandPool(); void createCommandPool();
void createPresentationRenderPass(); void createPresentationRenderPass();
void createDescriptorPool(); void createDescriptorPool();
void createMaterialSetLayout();
VkInstance instance_ = nullptr; VkInstance instance_ = nullptr;
@ -153,6 +162,8 @@ private:
VkDescriptorPool descriptorPool_ = nullptr; VkDescriptorPool descriptorPool_ = nullptr;
VkDescriptorSetLayout materialSetLayout_ = nullptr;
WorldPass* worldPass_ = nullptr; WorldPass* worldPass_ = nullptr;
PostPass* postPass_ = nullptr; PostPass* postPass_ = nullptr;
DoFPass* dofPass_ = nullptr; DoFPass* dofPass_ = nullptr;

View file

@ -2,6 +2,7 @@
layout(location = 0) in vec3 inFragPos; layout(location = 0) in vec3 inFragPos;
layout(location = 1) in vec3 inNormal; layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;
layout(location = 0) out vec4 outColor; layout(location = 0) out vec4 outColor;
@ -10,19 +11,21 @@ struct Light {
vec3 color; vec3 color;
}; };
layout(binding = 0) uniform Lights { layout(set = 0, binding = 0) uniform Lights {
Light lights[32]; Light lights[32];
}; };
layout(set = 1, binding = 0) uniform sampler2D albedoSampler;
void main() { void main() {
vec3 diffuse = vec3(0); vec3 diffuse = vec3(0);
for(int i = 0; i < 32; i++) { for(int i = 0; i < 32; i++) {
const vec3 norm = normalize(inNormal); const vec3 norm = normalize(inNormal);
const vec3 lightDir = normalize(lights[i].position.xyz - inFragPos); const vec3 lightDir = normalize(lights[i].position.xyz - inFragPos);
const float diff = max(dot(norm, lightDir), 0.0); const float diff = max(dot(norm, lightDir), 0.0);
diffuse += vec3(diff) * lights[i].color; diffuse += vec3(diff) * lights[i].color;
} }
outColor = vec4(vec3(0.1) + diffuse, 1.0); outColor = vec4(vec3(0.1) + diffuse * texture(albedoSampler, inUV).rgb, 1.0);
} }

View file

@ -2,9 +2,11 @@
layout(location = 0) in vec3 inPosition; layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal; layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;
layout(location = 0) out vec3 outFragPos; layout(location = 0) out vec3 outFragPos;
layout(location = 1) out vec3 outNormal; layout(location = 1) out vec3 outNormal;
layout(location = 2) out vec2 outUV;
layout(push_constant) uniform PushConstants { layout(push_constant) uniform PushConstants {
mat4 mvp; mat4 mvp;
@ -14,4 +16,5 @@ void main() {
gl_Position = pushConstants.mvp * vec4(inPosition, 1.0); gl_Position = pushConstants.mvp * vec4(inPosition, 1.0);
outFragPos = inPosition; outFragPos = inPosition;
outNormal = inNormal; outNormal = inNormal;
outUV = inUV;
} }

View file

@ -16,6 +16,7 @@
#include "light.h" #include "light.h"
#include "camera.h" #include "camera.h"
#include "cinematic.h" #include "cinematic.h"
#include "material.h"
SDL_Window* window = nullptr; SDL_Window* window = nullptr;
Renderer* renderer = nullptr; Renderer* renderer = nullptr;
@ -111,6 +112,7 @@ Mesh* loadMesh(const char* path) {
Vertex vertex; Vertex vertex;
vertex.position = glm::vec3(m->mVertices[i].x, m->mVertices[i].y, m->mVertices[i].z); vertex.position = glm::vec3(m->mVertices[i].x, m->mVertices[i].y, m->mVertices[i].z);
vertex.normal = glm::vec3(m->mNormals[i].x, m->mNormals[i].y, m->mNormals[i].z); vertex.normal = glm::vec3(m->mNormals[i].x, m->mNormals[i].y, m->mNormals[i].z);
vertex.uv = glm::vec2(m->mTextureCoords[0][i].x, m->mTextureCoords[0][i].y);
mesh->vertices.push_back(vertex); mesh->vertices.push_back(vertex);
} }
@ -220,19 +222,19 @@ int main(int argc, char* argv[]) {
SDL_SetWindowFullscreen(window, windowFullscreen == 1 ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); SDL_SetWindowFullscreen(window, windowFullscreen == 1 ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
ImGui::CreateContext(); ImGui::CreateContext();
auto& io = ImGui::GetIO(); auto& io = ImGui::GetIO();
io.DisplaySize = ImVec2(windowWidth, windowHeight); io.DisplaySize = ImVec2(windowWidth, windowHeight);
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
renderer = new Renderer(); renderer = new Renderer();
VkSurfaceKHR surface = nullptr; VkSurfaceKHR surface = nullptr;
SDL_Vulkan_CreateSurface(window, renderer->getInstance(), &surface); SDL_Vulkan_CreateSurface(window, renderer->getInstance(), &surface);
RenderTarget* target = renderer->createSurfaceRenderTarget(surface); RenderTarget* target = renderer->createSurfaceRenderTarget(surface);
World world; World world;
auto light = new Light(); auto light = new Light();
@ -245,14 +247,23 @@ int main(int argc, char* argv[]) {
if(cinematicMode) if(cinematicMode)
cinematic = loadCinematic(argv[2]); cinematic = loadCinematic(argv[2]);
else else {
world.meshes.push_back(loadMesh("data/scene.obj")); Material* material = new Material();
material->albedoTexturePath = "data/tile.jpg";
renderer->fillMaterialBuffers(material);
Mesh* mesh = loadMesh("data/scene.obj");
mesh->material = material;
world.meshes.push_back(mesh);
}
float currentTime = 0.0f, lastTime = 0.0f, animationTime = 0.0f; float currentTime = 0.0f, lastTime = 0.0f, animationTime = 0.0f;
Shot* currentShot = nullptr; Shot* currentShot = nullptr;
bool running = true; bool running = true;
while(running) { while(running) {
SDL_Event event = {}; SDL_Event event = {};
while(SDL_PollEvent(&event) > 0) { while(SDL_PollEvent(&event) > 0) {
if(event.type == SDL_QUIT) if(event.type == SDL_QUIT)
@ -261,7 +272,7 @@ int main(int argc, char* argv[]) {
if(event.type == SDL_WINDOWEVENT) { if(event.type == SDL_WINDOWEVENT) {
if(event.window.event == SDL_WINDOWEVENT_RESIZED) { if(event.window.event == SDL_WINDOWEVENT_RESIZED) {
io.DisplaySize = ImVec2(event.window.data1, event.window.data2); io.DisplaySize = ImVec2(event.window.data1, event.window.data2);
target = renderer->createSurfaceRenderTarget(surface, target); target = renderer->createSurfaceRenderTarget(surface, target);
} }
} }
@ -332,31 +343,31 @@ int main(int argc, char* argv[]) {
} }
} }
} }
currentTime = SDL_GetTicks() / 1000.0f; currentTime = SDL_GetTicks() / 1000.0f;
const float deltaTime = currentTime - lastTime; const float deltaTime = currentTime - lastTime;
lastTime = currentTime; lastTime = currentTime;
ImGui::NewFrame(); ImGui::NewFrame();
io.DeltaTime = deltaTime; io.DeltaTime = deltaTime;
int mouseX = 0, mouseY = 0; int mouseX = 0, mouseY = 0;
const Uint32 mouseButtons = SDL_GetMouseState(&mouseX, &mouseY); const Uint32 mouseButtons = SDL_GetMouseState(&mouseX, &mouseY);
io.MouseDown[0] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; io.MouseDown[0] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
io.MouseDown[1] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[1] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
io.MouseDown[2] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; io.MouseDown[2] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)
io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY)); io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
ImGui::DragFloat("Aperture", &camera.aperture, 0.01f, 0.0f, 1.0f); ImGui::DragFloat("Aperture", &camera.aperture, 0.01f, 0.0f, 1.0f);
ImGui::DragFloat("Focus Distance", &camera.focusDistance); ImGui::DragFloat("Focus Distance", &camera.focusDistance);
ImGui::Text("dpack[2] = %f", (100 - camera.focusDistance) / 100.0f); ImGui::Text("dpack[2] = %f", (100 - camera.focusDistance) / 100.0f);
ImGui::Render(); ImGui::Render();
renderer->render(world, camera, target); renderer->render(world, camera, target);
if(cinematicMode) { if(cinematicMode) {
animationTime += deltaTime; animationTime += deltaTime;
@ -369,6 +380,9 @@ int main(int argc, char* argv[]) {
} }
if(cinematic == nullptr) { if(cinematic == nullptr) {
renderer->destroyMaterialBuffers(world.meshes[0]->material);
delete world.meshes[0]->material;
renderer->destroyMeshBuffers(world.meshes[0]); renderer->destroyMeshBuffers(world.meshes[0]);
delete world.meshes[0]; delete world.meshes[0];
} }

View file

@ -7,10 +7,12 @@
#include <cstring> #include <cstring>
#include <cmath> #include <cmath>
#include <array> #include <array>
#include <stb_image.h>
#include "platform.h" #include "platform.h"
#include "mesh.h" #include "mesh.h"
#include "camera.h" #include "camera.h"
#include "material.h"
Renderer::Renderer() { Renderer::Renderer() {
createInstance(); createInstance();
@ -22,6 +24,7 @@ Renderer::Renderer() {
createCommandPool(); createCommandPool();
createPresentationRenderPass(); createPresentationRenderPass();
createDescriptorPool(); createDescriptorPool();
createMaterialSetLayout();
worldPass_ = new WorldPass(*this); worldPass_ = new WorldPass(*this);
postPass_ = new PostPass(*this); postPass_ = new PostPass(*this);
@ -37,6 +40,8 @@ Renderer::~Renderer() {
delete postPass_; delete postPass_;
delete worldPass_; delete worldPass_;
vkDestroyDescriptorSetLayout(device_, materialSetLayout_, nullptr);
vkDestroyDescriptorPool(device_, descriptorPool_, nullptr); vkDestroyDescriptorPool(device_, descriptorPool_, nullptr);
vkDestroyRenderPass(device_, presentationRenderPass_, nullptr); vkDestroyRenderPass(device_, presentationRenderPass_, nullptr);
@ -56,7 +61,7 @@ void Renderer::render(World& world, Camera& camera, RenderTarget* target) {
vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &target->imageIndex); vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &target->imageIndex);
target->currentResource = (target->imageIndex + 1) % numFrameResources; target->currentResource = (target->imageIndex + 1) % numFrameResources;
vkWaitForFences(device_, 1, &target->fences[target->currentResource], VK_TRUE, UINT64_MAX); vkWaitForFences(device_, 1, &target->fences[target->currentResource], VK_TRUE, UINT64_MAX);
vkResetFences(device_, 1, &target->fences[target->currentResource]); vkResetFences(device_, 1, &target->fences[target->currentResource]);
@ -81,11 +86,11 @@ void Renderer::render(World& world, Camera& camera, RenderTarget* target) {
worldPass_->render(commandBuffer, world, camera, target); worldPass_->render(commandBuffer, world, camera, target);
dofPass_->render(commandBuffer, camera, target); dofPass_->render(commandBuffer, camera, target);
// reset after dof pass // reset after dof pass
vkCmdSetViewport(commandBuffer, 0, 1, &viewport); vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
vkCmdSetScissor(commandBuffer, 0, 1, &scissor); vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
VkClearValue clearColor = {}; VkClearValue clearColor = {};
VkRenderPassBeginInfo renderPassBeginInfo = {}; VkRenderPassBeginInfo renderPassBeginInfo = {};
@ -189,7 +194,7 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
target->swapchainImages = new VkImage[swapchainImageCount]; target->swapchainImages = new VkImage[swapchainImageCount];
vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, target->swapchainImages); vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, target->swapchainImages);
// create frame resources // create frame resources
target->swapchainImageViews = new VkImageView[swapchainImageCount]; target->swapchainImageViews = new VkImageView[swapchainImageCount];
target->swapchainFramebuffers = new VkFramebuffer[swapchainImageCount]; target->swapchainFramebuffers = new VkFramebuffer[swapchainImageCount];
@ -347,7 +352,7 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->offscreenFramebuffers[i]); vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->offscreenFramebuffers[i]);
} }
// near field color // near field color
{ {
VkImageCreateInfo imageCreateInfo = {}; VkImageCreateInfo imageCreateInfo = {};
@ -362,21 +367,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_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->nearFieldImages[i]); vkCreateImage(device_, &imageCreateInfo, nullptr, &target->nearFieldImages[i]);
VkMemoryRequirements memoryRequirements = {}; VkMemoryRequirements memoryRequirements = {};
vkGetImageMemoryRequirements(device_, target->nearFieldImages[i], &memoryRequirements); vkGetImageMemoryRequirements(device_, target->nearFieldImages[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->nearFieldMemory[i]); vkAllocateMemory(device_, &allocateInfo, nullptr, &target->nearFieldMemory[i]);
vkBindImageMemory(device_, target->nearFieldImages[i], target->nearFieldMemory[i], 0); vkBindImageMemory(device_, target->nearFieldImages[i], target->nearFieldMemory[i], 0);
} }
// near field image view // near field image view
{ {
VkImageViewCreateInfo createInfo = {}; VkImageViewCreateInfo createInfo = {};
@ -387,12 +392,12 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.levelCount = 1; createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.layerCount = 1; createInfo.subresourceRange.layerCount = 1;
vkCreateImageView(device_, &createInfo, nullptr, &target->nearFieldImageViews[i]); vkCreateImageView(device_, &createInfo, nullptr, &target->nearFieldImageViews[i]);
} }
// near field framebuffer // near field framebuffer
{ {
VkFramebufferCreateInfo framebufferInfo = {}; VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = dofPass_->getRenderPass(); framebufferInfo.renderPass = dofPass_->getRenderPass();
@ -401,10 +406,10 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
framebufferInfo.width = target->extent.width / dofFramebufferDownscaleFactor; framebufferInfo.width = target->extent.width / dofFramebufferDownscaleFactor;
framebufferInfo.height = target->extent.height / dofFramebufferDownscaleFactor; framebufferInfo.height = target->extent.height / dofFramebufferDownscaleFactor;
framebufferInfo.layers = 1; framebufferInfo.layers = 1;
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->nearFieldFramebuffers[i]); vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->nearFieldFramebuffers[i]);
} }
// far field color // far field color
{ {
VkImageCreateInfo imageCreateInfo = {}; VkImageCreateInfo imageCreateInfo = {};
@ -419,21 +424,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_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->farFieldImages[i]); vkCreateImage(device_, &imageCreateInfo, nullptr, &target->farFieldImages[i]);
VkMemoryRequirements memoryRequirements = {}; VkMemoryRequirements memoryRequirements = {};
vkGetImageMemoryRequirements(device_, target->farFieldImages[i], &memoryRequirements); vkGetImageMemoryRequirements(device_, target->farFieldImages[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->farFieldMemory[i]); vkAllocateMemory(device_, &allocateInfo, nullptr, &target->farFieldMemory[i]);
vkBindImageMemory(device_, target->farFieldImages[i], target->farFieldMemory[i], 0); vkBindImageMemory(device_, target->farFieldImages[i], target->farFieldMemory[i], 0);
} }
// far field image view // far field image view
{ {
VkImageViewCreateInfo createInfo = {}; VkImageViewCreateInfo createInfo = {};
@ -444,12 +449,12 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.levelCount = 1; createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.layerCount = 1; createInfo.subresourceRange.layerCount = 1;
vkCreateImageView(device_, &createInfo, nullptr, &target->farFieldImageViews[i]); vkCreateImageView(device_, &createInfo, nullptr, &target->farFieldImageViews[i]);
} }
// far field framebuffer // far field framebuffer
{ {
VkFramebufferCreateInfo framebufferInfo = {}; VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = dofPass_->getRenderPass(); framebufferInfo.renderPass = dofPass_->getRenderPass();
@ -458,16 +463,16 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
framebufferInfo.width = target->extent.width / dofFramebufferDownscaleFactor; framebufferInfo.width = target->extent.width / dofFramebufferDownscaleFactor;
framebufferInfo.height = target->extent.height / dofFramebufferDownscaleFactor; framebufferInfo.height = target->extent.height / dofFramebufferDownscaleFactor;
framebufferInfo.layers = 1; framebufferInfo.layers = 1;
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->farFieldFramebuffers[i]); vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->farFieldFramebuffers[i]);
} }
// imgui // imgui
{ {
target->imguiVertexBuffers[i] = nullptr; target->imguiVertexBuffers[i] = nullptr;
target->imguiVertexMemorys[i] = nullptr; target->imguiVertexMemorys[i] = nullptr;
target->imguiVertexBufferSizes[i] = 0; target->imguiVertexBufferSizes[i] = 0;
target->imguiIndexBuffers[i] = nullptr; target->imguiIndexBuffers[i] = nullptr;
target->imguiIndexMemorys[i] = nullptr; target->imguiIndexMemorys[i] = nullptr;
target->imguiIndexBufferSizes[i] = 0; target->imguiIndexBufferSizes[i] = 0;
@ -526,22 +531,22 @@ void Renderer::destroyRenderTarget(RenderTarget* target) {
for(uint32_t i = 0; i < target->numImages; i++) { for(uint32_t i = 0; i < target->numImages; i++) {
vkFreeMemory(device_, target->imguiIndexMemorys[i], nullptr); vkFreeMemory(device_, target->imguiIndexMemorys[i], nullptr);
vkDestroyBuffer(device_, target->imguiIndexBuffers[i], nullptr); vkDestroyBuffer(device_, target->imguiIndexBuffers[i], nullptr);
vkFreeMemory(device_, target->imguiVertexMemorys[i], nullptr); vkFreeMemory(device_, target->imguiVertexMemorys[i], nullptr);
vkDestroyBuffer(device_, target->imguiVertexBuffers[i], nullptr); vkDestroyBuffer(device_, target->imguiVertexBuffers[i], nullptr);
vkDestroyFramebuffer(device_, target->nearFieldFramebuffers[i], nullptr); vkDestroyFramebuffer(device_, target->nearFieldFramebuffers[i], nullptr);
vkDestroyImageView(device_, target->nearFieldImageViews[i], nullptr); vkDestroyImageView(device_, target->nearFieldImageViews[i], nullptr);
vkFreeMemory(device_, target->nearFieldMemory[i], nullptr); vkFreeMemory(device_, target->nearFieldMemory[i], nullptr);
vkDestroyImage(device_, target->nearFieldImages[i], nullptr); vkDestroyImage(device_, target->nearFieldImages[i], nullptr);
vkDestroyFramebuffer(device_, target->farFieldFramebuffers[i], nullptr); vkDestroyFramebuffer(device_, target->farFieldFramebuffers[i], nullptr);
vkDestroyImageView(device_, target->farFieldImageViews[i], nullptr); vkDestroyImageView(device_, target->farFieldImageViews[i], nullptr);
vkFreeMemory(device_, target->farFieldMemory[i], nullptr); vkFreeMemory(device_, target->farFieldMemory[i], nullptr);
vkDestroyImage(device_, target->farFieldImages[i], nullptr); vkDestroyImage(device_, target->farFieldImages[i], nullptr);
vkDestroyFramebuffer(device_, target->offscreenFramebuffers[i], nullptr); vkDestroyFramebuffer(device_, target->offscreenFramebuffers[i], nullptr);
vkDestroyImageView(device_, target->offscreenDepthImageViews[i], nullptr); vkDestroyImageView(device_, target->offscreenDepthImageViews[i], nullptr);
@ -555,31 +560,31 @@ 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->imguiIndexBufferSizes; delete[] target->imguiIndexBufferSizes;
delete[] target->imguiIndexMemorys; delete[] target->imguiIndexMemorys;
delete[] target->imguiIndexBuffers; delete[] target->imguiIndexBuffers;
delete[] target->imguiVertexBufferSizes; delete[] target->imguiVertexBufferSizes;
delete[] target->imguiVertexMemorys; delete[] target->imguiVertexMemorys;
delete[] target->imguiVertexBuffers; delete[] target->imguiVertexBuffers;
delete[] target->nearFieldFramebuffers; delete[] target->nearFieldFramebuffers;
delete[] target->nearFieldImageViews; delete[] target->nearFieldImageViews;
delete[] target->nearFieldMemory; delete[] target->nearFieldMemory;
delete[] target->nearFieldImages; delete[] target->nearFieldImages;
delete[] target->farFieldFramebuffers; delete[] target->farFieldFramebuffers;
delete[] target->farFieldImageViews; delete[] target->farFieldImageViews;
delete[] target->farFieldMemory; delete[] target->farFieldMemory;
delete[] target->farFieldImages; delete[] target->farFieldImages;
delete[] target->offscreenFramebuffers; delete[] target->offscreenFramebuffers;
delete[] target->offscreenDepthImageViews; delete[] target->offscreenDepthImageViews;
delete[] target->offscreenDepthMemory; delete[] target->offscreenDepthMemory;
delete[] target->offscreenDepthImages; delete[] target->offscreenDepthImages;
delete[] target->offscreenColorImageViews; delete[] target->offscreenColorImageViews;
delete[] target->offscreenColorMemory; delete[] target->offscreenColorMemory;
delete[] target->offscreenColorImages; delete[] target->offscreenColorImages;
@ -823,44 +828,44 @@ VkShaderModule Renderer::createShader(const char* path) {
void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src) { void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src) {
VkBuffer stagingBuffer; VkBuffer stagingBuffer;
VkDeviceMemory stagingMemory; VkDeviceMemory stagingMemory;
VkBufferCreateInfo bufferInfo = {}; VkBufferCreateInfo bufferInfo = {};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size; bufferInfo.size = size;
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
vkCreateBuffer(device_, &bufferInfo, nullptr, &stagingBuffer); vkCreateBuffer(device_, &bufferInfo, nullptr, &stagingBuffer);
VkMemoryRequirements memRequirements = {}; VkMemoryRequirements memRequirements = {};
vkGetBufferMemoryRequirements(device_, stagingBuffer, &memRequirements); vkGetBufferMemoryRequirements(device_, stagingBuffer, &memRequirements);
VkMemoryAllocateInfo allocInfo = {}; VkMemoryAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size; allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
vkAllocateMemory(device_, &allocInfo, nullptr, &stagingMemory); vkAllocateMemory(device_, &allocInfo, nullptr, &stagingMemory);
vkBindBufferMemory(device_, stagingBuffer, stagingMemory, 0); vkBindBufferMemory(device_, stagingBuffer, stagingMemory, 0);
void* data; void* data;
vkMapMemory(device_, stagingMemory, 0, size, 0, &data); vkMapMemory(device_, stagingMemory, 0, size, 0, &data);
memcpy(data, src, size); memcpy(data, src, size);
vkUnmapMemory(device_, stagingMemory); vkUnmapMemory(device_, stagingMemory);
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 layout to transfer dst // change layout to transfer dst
{ {
VkImageMemoryBarrier imageMemoryBarrier = {}; VkImageMemoryBarrier imageMemoryBarrier = {};
@ -871,7 +876,7 @@ void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSiz
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,
@ -881,14 +886,14 @@ void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSiz
0, nullptr, 0, nullptr,
1, &imageMemoryBarrier); 1, &imageMemoryBarrier);
} }
VkBufferImageCopy region = {}; VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.layerCount = 1; region.imageSubresource.layerCount = 1;
region.imageExtent.width = width; region.imageExtent.width = width;
region.imageExtent.height = height; region.imageExtent.height = height;
region.imageExtent.depth = 1; region.imageExtent.depth = 1;
vkCmdCopyBufferToImage( vkCmdCopyBufferToImage(
commandBuffer, commandBuffer,
stagingBuffer, stagingBuffer,
@ -897,7 +902,7 @@ void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSiz
1, 1,
&region &region
); );
// change layout to shader read only // change layout to shader read only
{ {
VkImageMemoryBarrier imageMemoryBarrier = {}; VkImageMemoryBarrier imageMemoryBarrier = {};
@ -910,7 +915,7 @@ void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSiz
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,
@ -920,27 +925,27 @@ void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSiz
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, VK_TRUE, -1); vkWaitForFences(device_, 1, &fence, VK_TRUE, -1);
vkDestroyFence(device_, fence, nullptr); vkDestroyFence(device_, fence, nullptr);
vkFreeCommandBuffers(device_, commandPool_, 1, &commandBuffer); vkFreeCommandBuffers(device_, commandPool_, 1, &commandBuffer);
vkFreeMemory(device_, stagingMemory, nullptr); vkFreeMemory(device_, stagingMemory, nullptr);
vkDestroyBuffer(device_, stagingBuffer, nullptr); vkDestroyBuffer(device_, stagingBuffer, nullptr);
} }
@ -1012,6 +1017,106 @@ void Renderer::fillMeshBuffers(Mesh* mesh) {
} }
} }
void Renderer::fillMaterialBuffers(Material* material) {
int width = 0, height = 0, channels = 0;
stbi_uc* pixels = stbi_load(material->albedoTexturePath.c_str(), &width, &height, &channels, STBI_rgb_alpha);
if(pixels == nullptr)
return; // haha what
VkImageCreateInfo imageCreateInfo = {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.extent.width = width;
imageCreateInfo.extent.height = height;
imageCreateInfo.extent.depth = 1;
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
vkCreateImage(device_, &imageCreateInfo, nullptr, &material->albedoImage);
VkMemoryRequirements memRequirements;
vkGetImageMemoryRequirements(device_, material->albedoImage, &memRequirements);
VkMemoryAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vkAllocateMemory(device_, &allocInfo, nullptr, &material->albedoMemory);
vkBindImageMemory(device_, material->albedoImage, material->albedoMemory, 0);
uploadImageData(
material->albedoImage,
width,
height,
width * height * 4,
pixels
);
stbi_image_free(pixels);
VkImageViewCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = material->albedoImage;
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.layerCount = 1;
vkCreateImageView(device_, &createInfo, nullptr, &material->albedoImageView);
VkSamplerCreateInfo samplerInfo = {};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
vkCreateSampler(device_, &samplerInfo, nullptr, &material->albedoSampler);
VkDescriptorSetAllocateInfo setAllocInfo = {};
setAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
setAllocInfo.descriptorPool = descriptorPool_;
setAllocInfo.descriptorSetCount = 1;
setAllocInfo.pSetLayouts = &materialSetLayout_;
vkAllocateDescriptorSets(device_, &setAllocInfo, &material->set);
VkDescriptorImageInfo albedoImageInfo = {};
albedoImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
albedoImageInfo.imageView = material->albedoImageView;
albedoImageInfo.sampler = material->albedoSampler;
VkWriteDescriptorSet albedoDescriptorWrite = {};
albedoDescriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
albedoDescriptorWrite.descriptorCount = 1;
albedoDescriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
albedoDescriptorWrite.dstSet = material->set;
albedoDescriptorWrite.pImageInfo = &albedoImageInfo;
vkUpdateDescriptorSets(device_, 1, &albedoDescriptorWrite, 0, nullptr);
}
void Renderer::destroyMaterialBuffers(Material* material) {
vkDeviceWaitIdle(device_);
vkFreeDescriptorSets(device_, descriptorPool_, 1, &material->set);
vkDestroySampler(device_, material->albedoSampler, nullptr);
vkDestroyImageView(device_, material->albedoImageView, nullptr);
vkFreeMemory(device_, material->albedoMemory, nullptr);
vkDestroyImage(device_, material->albedoImage, nullptr);
}
void Renderer::destroyMeshBuffers(Mesh* mesh) { void Renderer::destroyMeshBuffers(Mesh* mesh) {
vkDeviceWaitIdle(device_); vkDeviceWaitIdle(device_);
@ -1203,3 +1308,17 @@ void Renderer::createDescriptorPool() {
vkCreateDescriptorPool(device_, &poolInfo, nullptr, &descriptorPool_); vkCreateDescriptorPool(device_, &poolInfo, nullptr, &descriptorPool_);
} }
void Renderer::createMaterialSetLayout() {
VkDescriptorSetLayoutBinding albedoSamplerBinding = {};
albedoSamplerBinding.descriptorCount = 1;
albedoSamplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
albedoSamplerBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorSetLayoutCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
createInfo.bindingCount = 1;
createInfo.pBindings = &albedoSamplerBinding;
vkCreateDescriptorSetLayout(device_, &createInfo, nullptr, &materialSetLayout_);
}

View file

@ -8,6 +8,7 @@
#include "mesh.h" #include "mesh.h"
#include "light.h" #include "light.h"
#include "camera.h" #include "camera.h"
#include "material.h"
WorldPass::WorldPass(Renderer& renderer) : renderer_(renderer) { WorldPass::WorldPass(Renderer& renderer) : renderer_(renderer) {
createRenderPass(); createRenderPass();
@ -64,6 +65,8 @@ void WorldPass::render(VkCommandBuffer commandBuffer, World& world, Camera& came
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &descriptorSet_, 0, nullptr); vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &descriptorSet_, 0, nullptr);
for(const auto& mesh : world.meshes) { for(const auto& mesh : world.meshes) {
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 1, 1, &mesh->material->set, 0, nullptr);
glm::mat4 mvp; glm::mat4 mvp;
mvp = glm::perspective(glm::radians(75.0f), (float)target->extent.width / target->extent.height, camera.near, camera.far); mvp = glm::perspective(glm::radians(75.0f), (float)target->extent.width / target->extent.height, camera.near, camera.far);
mvp *= glm::lookAt(camera.position, camera.target, glm::vec3(0, -1, 0)); mvp *= glm::lookAt(camera.position, camera.target, glm::vec3(0, -1, 0));
@ -173,9 +176,15 @@ void WorldPass::createPipeline() {
normalAttributeDescription.offset = offsetof(Vertex, normal); normalAttributeDescription.offset = offsetof(Vertex, normal);
normalAttributeDescription.format = VK_FORMAT_R32G32B32_SFLOAT; normalAttributeDescription.format = VK_FORMAT_R32G32B32_SFLOAT;
const std::array<VkVertexInputAttributeDescription, 2> attributes = { VkVertexInputAttributeDescription uvAttributeDescription = {};
uvAttributeDescription.location = 2;
uvAttributeDescription.offset = offsetof(Vertex, uv);
uvAttributeDescription .format = VK_FORMAT_R32G32_SFLOAT;
const std::array<VkVertexInputAttributeDescription, 3> attributes = {
positionAttributeDescription, positionAttributeDescription,
normalAttributeDescription normalAttributeDescription,
uvAttributeDescription
}; };
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
@ -234,10 +243,15 @@ void WorldPass::createPipeline() {
mvpPushConstant.size = sizeof(glm::mat4); mvpPushConstant.size = sizeof(glm::mat4);
mvpPushConstant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; mvpPushConstant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
const std::array<VkDescriptorSetLayout, 2> setLayouts = {
setLayout_,
renderer_.getMaterialSetLayout()
};
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 1; pipelineLayoutInfo.setLayoutCount = setLayouts.size();
pipelineLayoutInfo.pSetLayouts = &setLayout_; pipelineLayoutInfo.pSetLayouts = setLayouts.data();
pipelineLayoutInfo.pushConstantRangeCount = 1; pipelineLayoutInfo.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &mvpPushConstant; pipelineLayoutInfo.pPushConstantRanges = &mvpPushConstant;