Add material class
This commit is contained in:
parent
b53e2bb9ce
commit
0c970b0236
12 changed files with 4643 additions and 2363 deletions
|
@ -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
12
data/scene.mtl
Normal 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
|
6614
data/scene.obj
6614
data/scene.obj
File diff suppressed because it is too large
Load diff
BIN
data/tile.jpg
Normal file
BIN
data/tile.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
16
include/material.h
Normal file
16
include/material.h
Normal 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;
|
||||||
|
};
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
44
src/main.cpp
44
src/main.cpp
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
245
src/renderer.cpp
245
src/renderer.cpp
|
@ -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,
|
||||||
®ion
|
®ion
|
||||||
);
|
);
|
||||||
|
|
||||||
// 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_);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Reference in a new issue