Commit 15f5b090 authored by Shu's avatar Shu 🍠
Browse files

Voxel pass

parent 74e15617
......@@ -3,7 +3,6 @@
#include "PhysicalDeviceInfo.hpp"
#include "Pipeline.hpp"
#include "Renderer.hpp"
#include "buffer/VertexData.hpp"
using namespace render::vk;
......@@ -23,15 +22,6 @@ CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, co
}
}
modelBuffer = ShortIndexedVertexBuffer::Create(buffer::vk::vertices, buffer::vk::indices);
if (!modelBuffer) {
FATAL("Cannot create vertex buffer");
}
sampleTexture = Texture::LoadFromFile(TEXTURES_DIR + opt.textures + "/terrain/Mapl.dds", {true, true, Texture::Wrap::MIRRORED_REPEAT, opt.anisotropy});
if (!sampleTexture) {
FATAL("Failed to create texture sampler!");
}
indicCubeBuffer = Indicator::Create(Indicator::CUBE.first, Indicator::CUBE.second);
if (!indicCubeBuffer) {
FATAL("Failed to create vertex buffer!");
......@@ -50,6 +40,8 @@ CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, co
colorSamples = info.samples;
LOG_D("Samples: " << colorSamples);
depthFormat = info.findDepthFormat();
loadAtlases(opt.textures);
}
CommandCenter::~CommandCenter() {
if(!freed)
......@@ -57,6 +49,30 @@ CommandCenter::~CommandCenter() {
vkDestroyCommandPool(device, graphicsPool, ALLOC);
}
#include "../../../core/world/materials.hpp"
void CommandCenter::loadAtlases(const std::string& textures) {
voxelTextureAtlas.reset();
voxelNormalAtlas.reset();
voxelHOSAtlas.reset();
std::vector<std::string> paths;
auto makePaths = [&](const std::string &suffix) {
paths.clear();
paths.reserve(world::materials::textures.size());
for (auto& texture: world::materials::textures) {
paths.push_back(TEXTURES_DIR + textures + "/terrain/" + texture + suffix + ".dds");
}
return paths;
};
voxelTextureAtlas = TextureArray::LoadFromFiles(makePaths(""), {}); //TODO: anisotropy/mipmap options
voxelNormalAtlas = TextureArray::LoadFromFiles(makePaths(".nrm"), {});
voxelHOSAtlas = TextureArray::LoadFromFiles(makePaths(".hos"), {});
if(!(voxelTextureAtlas && voxelNormalAtlas && voxelHOSAtlas)) {
FATAL("Failed to load texture pack!");
}
}
#include <glm/gtc/matrix_transform.hpp>
void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent) {
assert(freed);
......@@ -97,7 +113,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
{ // Uniform buffers
std::vector<Buffer::requirement> requirements;
requirements.resize(framebuffers.size(), Buffer::requirement(sizeof(UniformBufferObject), Buffer::Usage::UNIFORM));
requirements.resize(framebuffers.size(), Buffer::requirement(sizeof(VoxelUBO), Buffer::Usage::UNIFORM));
uniformBuffers.allocate(requirements, true);
if (!uniformBuffers) {
FATAL("Failed to allocate UBO");
......@@ -108,7 +124,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSizes[0].descriptorCount = framebuffers.size();
poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
poolSizes[1].descriptorCount = framebuffers.size();
poolSizes[1].descriptorCount = framebuffers.size() * 3;
VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
......@@ -121,12 +137,13 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
FATAL("Failed to create descriptor pool!");
}
poolSizes[1].descriptorCount = framebuffers.size();
if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &skyDescriptorPool) != VK_SUCCESS) {
FATAL("Failed to create descriptor pool!");
}
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSizes[0];
if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &indicDescriptorPool) != VK_SUCCESS) {
FATAL("Failed to create descriptor pool!");
......@@ -155,7 +172,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = uniformBuffers.at(i);
bufferInfo.offset = 0;
bufferInfo.range = sizeof(UniformBufferObject);
bufferInfo.range = sizeof(VoxelUBO);
std::array<VkWriteDescriptorSet, 2> descriptorWrites{};
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
......@@ -172,17 +189,33 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
descriptorWrites[1].dstArrayElement = 0;
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[1].descriptorCount = 1;
descriptorWrites[1].pImageInfo = &sampleTexture->getDescriptor();
descriptorWrites[1].pImageInfo = &voxelTextureAtlas->getDescriptor();
descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[2].dstSet = voxelDescriptorSets[i];
descriptorWrites[2].dstBinding = 2;
descriptorWrites[2].dstArrayElement = 0;
descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[2].descriptorCount = 1;
descriptorWrites[2].pImageInfo = &voxelNormalAtlas->getDescriptor();
descriptorWrites[3].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[3].dstSet = voxelDescriptorSets[i];
descriptorWrites[3].dstBinding = 3;
descriptorWrites[3].dstArrayElement = 0;
descriptorWrites[3].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[3].descriptorCount = 1;
descriptorWrites[3].pImageInfo = &voxelHOSAtlas->getDescriptor();
vkUpdateDescriptorSets(device, descriptorWrites.size(), descriptorWrites.data(), 0, nullptr);
bufferInfo.range = sizeof(ViewProjUBO);
descriptorWrites[0].dstSet = skyDescriptorSets[i];
descriptorWrites[1].dstSet = skyDescriptorSets[i];
descriptorWrites[1].pImageInfo = &skyboxTexture->getDescriptor();
vkUpdateDescriptorSets(device, descriptorWrites.size(), descriptorWrites.data(), 0, nullptr);
vkUpdateDescriptorSets(device, 2, descriptorWrites.data(), 0, nullptr);
descriptorWrites[0].dstSet = indicDescriptorSets[i];
vkUpdateDescriptorSets(device, 1, &descriptorWrites[0], 0, nullptr);
vkUpdateDescriptorSets(device, 1, descriptorWrites.data(), 0, nullptr);
}
}
{
......@@ -221,10 +254,7 @@ void CommandCenter::free() {
#include <chrono>
#include <memory.h>
void CommandCenter::startRecording(uint32_t idx, VkRenderPass renderPass, VkExtent2D extent, const glm::vec4& clear_color, glm::mat4 view, glm::mat4 proj) {
UniformBufferObject ubo{};
ubo.view = view;
ubo.proj = proj;
void CommandCenter::startRecording(uint32_t idx, VkRenderPass renderPass, VkExtent2D extent, const VoxelUBO& ubo) {
uniformBuffers.write(idx, data_view(&ubo, sizeof(ubo)));
VkCommandBufferBeginInfo beginInfo{};
......@@ -245,7 +275,7 @@ void CommandCenter::startRecording(uint32_t idx, VkRenderPass renderPass, VkExte
renderPassInfo.renderArea.extent = extent;
std::array<VkClearValue, 2> clearValues{};
clearValues[0].color = {clear_color.x, clear_color.y, clear_color.z, clear_color.a};
clearValues[0].color = {ubo.fog.x, ubo.fog.y, ubo.fog.z, 1};
clearValues[1].depthStencil = {1.0f, 0};
renderPassInfo.clearValueCount = clearValues.size();
renderPassInfo.pClearValues = clearValues.data();
......@@ -256,22 +286,17 @@ void CommandCenter::startRecording(uint32_t idx, VkRenderPass renderPass, VkExte
void CommandCenter::startWorldPass(uint32_t idx, const Subpass &worldPass) {
vkCmdBindPipeline(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, worldPass.pipeline);
vkCmdBindDescriptorSets(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, worldPass.layout, 0, 1, &voxelDescriptorSets[idx], 0, nullptr);
static auto startTime = std::chrono::high_resolution_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();
ModelPush push{};
push.model = glm::translate(glm::mat4(1.0f), glm::vec3(98.0f, -2.f, -2.f));
push.model = glm::rotate(push.model, time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
vkCmdPushConstants(graphicsBuffers[idx], worldPass.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push), &push);
}
void CommandCenter::recordModel(uint32_t i) {
size_t CommandCenter::recordModel(uint32_t i, const Subpass &worldPass, const UniqueCurvaturePush& push, const LodModel *const modelBuffer) {
vkCmdPushConstants(graphicsBuffers[i], worldPass.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(push), &push);
VkBuffer vertexBuffers[] = {modelBuffer->getVertex()};
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(graphicsBuffers[i], 0, 1, vertexBuffers, offsets);
vkCmdBindIndexBuffer(graphicsBuffers[i], modelBuffer->getIndex(), 0, VK_INDEX_TYPE_UINT16);
vkCmdDrawIndexed(graphicsBuffers[i], static_cast<uint32_t>(buffer::vk::indices.size()), 1, 0, 0, 0);
auto size = modelBuffer->getIndexSize();
vkCmdDrawIndexed(graphicsBuffers[i], size, 1, modelBuffer->getIndexStart(), 0, 0);
return size;
}
void CommandCenter::startEntityPass(uint32_t) { }
void CommandCenter::recordIndicator(uint32_t idx, const Subpass& indicPass, glm::mat4 model) {
......@@ -287,7 +312,7 @@ void CommandCenter::recordIndicator(uint32_t idx, const Subpass& indicPass, glm:
vkCmdBindVertexBuffers(graphicsBuffers[idx], 0, 1, vertexBuffers, offsets);
vkCmdDraw(graphicsBuffers[idx], indicCubeBuffer->size, 1, 0, 0);
}
void CommandCenter::recordPostprocess(uint32_t idx, const Subpass& skyPass, bool skybox, glm::mat4, glm::mat4) {
void CommandCenter::recordPostprocess(uint32_t idx, const Subpass& skyPass, bool skybox) {
vkCmdNextSubpass(graphicsBuffers[idx], VK_SUBPASS_CONTENTS_INLINE);
if (skybox) {
vkCmdBindPipeline(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, skyPass.pipeline);
......
......@@ -17,18 +17,20 @@ public:
CommandCenter(VkDevice, const PhysicalDeviceInfo&, const renderOptions&);
~CommandCenter();
void startRecording(uint32_t idx, VkRenderPass, VkExtent2D, const glm::vec4& clear, glm::mat4 view, glm::mat4 proj);
void startRecording(uint32_t idx, VkRenderPass, VkExtent2D, const VoxelUBO&);
void startWorldPass(uint32_t idx, const Subpass&);
void recordModel(uint32_t idx);
size_t recordModel(uint32_t idx, const Subpass &worldPass, const UniqueCurvaturePush&, const LodModel *const);
void startEntityPass(uint32_t idx);
void recordIndicator(uint32_t idx, const Subpass&, glm::mat4 model);
void recordPostprocess(uint32_t idx, const Subpass&, bool skybox, glm::mat4 view, glm::mat4 proj);
void recordPostprocess(uint32_t idx, const Subpass&, bool skybox);
void submitGraphics(uint32_t, VkSemaphore, VkSemaphore, VkFence);
void allocate(const std::vector<VkImageView>&, const Pipeline&, VkExtent2D);
void free();
private:
void loadAtlases(const std::string &texturePath);
VkDevice device;
std::vector<VkFramebuffer> framebuffers;
......@@ -47,8 +49,9 @@ private:
VkDescriptorPool voxelDescriptorPool;
std::vector<VkDescriptorSet> voxelDescriptorSets;
std::unique_ptr<Texture> sampleTexture;
std::unique_ptr<ShortIndexedVertexBuffer> modelBuffer;
std::unique_ptr<TextureArray> voxelTextureAtlas;
std::unique_ptr<TextureArray> voxelNormalAtlas;
std::unique_ptr<TextureArray> voxelHOSAtlas;
VkDescriptorPool indicDescriptorPool;
std::vector<VkDescriptorSet> indicDescriptorSets;
......
......@@ -3,7 +3,6 @@
#include "PhysicalDeviceInfo.hpp"
#include "../../../core/data/file.hpp"
#include "../Renderer.hpp"
#include "buffer/VertexData.hpp"
#include "api/Models.hpp"
#include <map>
......@@ -129,15 +128,26 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
}
}
//MAYBE: use sets (ubo, (samplers, passInfos))
//MAYBE: reuse sub UBO
{ // Voxel descriptor
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
samplerLayoutBinding.binding = 1;
samplerLayoutBinding.descriptorCount = 1;
samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
samplerLayoutBinding.pImmutableSamplers = nullptr;
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
std::array<VkDescriptorSetLayoutBinding, 4> bindings{};
bindings[0] = VoxelUBO::getLayoutBinding();
bindings[1].binding = 1;
bindings[1].descriptorCount = 1;
bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[1].pImmutableSamplers = nullptr; //TODO: set immuable samplers
bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[2].binding = 2;
bindings[2].descriptorCount = 1;
bindings[2].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[2].pImmutableSamplers = nullptr;
bindings[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[3].binding = 3;
bindings[3].descriptorCount = 1;
bindings[3].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[3].pImmutableSamplers = nullptr;
bindings[3].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
std::vector<VkDescriptorSetLayoutBinding> bindings = {UniformBufferObject::getLayoutBinding(), samplerLayoutBinding};
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = bindings.size();
......@@ -150,7 +160,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
{ // Indicator descriptor
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
auto binding = UniformBufferObject::getLayoutBinding();
auto binding = ViewProjUBO::getLayoutBinding();
layoutInfo.bindingCount = 1;
layoutInfo.pBindings = &binding;
......@@ -166,7 +176,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
samplerLayoutBinding.pImmutableSamplers = nullptr;
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
std::vector<VkDescriptorSetLayoutBinding> bindings = {UniformBufferObject::getLayoutBinding(), samplerLayoutBinding};
std::vector<VkDescriptorSetLayoutBinding> bindings = {ViewProjUBO::getLayoutBinding(), samplerLayoutBinding};
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = bindings.size();
......@@ -342,25 +352,35 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
multisampling.alphaToOneEnable = VK_FALSE;
{ // World pipeline
/*struct Push {
alignas(16) glm::mat4 Model;
alignas(16) glm::vec4 SphereProj;
alignas(4) float Curvature;
};*/
VkPushConstantRange pushRange{};
pushRange.offset = 0;
pushRange.size = sizeof(ModelPush);
pushRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
setLayout(worldPass, {voxelDescriptorSet}, {pushRange});
auto shaderStages = setShaders(worldPass, "Tris");
auto unitSize = 1; //TODO: load from world.voxel_density
std::vector<unsigned char> speData;
std::vector<VkSpecializationMapEntry> speIndex;
auto specialization = makeSpecialization({
{0, data_view(&options.voxel.fog, sizeof(bool))},
{1, data_view(&options.voxel.pbr, sizeof(bool))},
{2, data_view(&options.voxel.triplanar, sizeof(bool))},
{3, data_view(&options.voxel.stochastic, sizeof(bool))},
{4, data_view(&options.voxel.blend, sizeof(bool))},
{5, data_view(&options.voxel.curvature, sizeof(bool))},
{6, data_view(&options.voxel.curv_depth, sizeof(bool))},
{16, data_view(&unitSize, sizeof(int))}}, speData, speIndex);
auto withGeometry = options.voxel.geometry; //MAYBE: && features.geometry
auto shaderStages = setShaders(worldPass, withGeometry ? "Tris.geo" : "Tris", withGeometry, &specialization);
VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
auto bindingDescription = buffer::vk::VertexData::getBindingDescription();
auto bindingDescription = Model::getBindingDescription();
vertexInputInfo.vertexBindingDescriptionCount = 1;
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
auto attributeDescriptions = buffer::vk::VertexData::getAttributeDescriptions();
auto attributeDescriptions = Model::getAttributeDescriptions();
vertexInputInfo.vertexAttributeDescriptionCount = attributeDescriptions.size();
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
......
......@@ -411,8 +411,14 @@ void Renderer::beginFrame() {
if (auto newImage = swapChain->acquireNextImage(imageAvailableSemaphores[currentFrame], inFlightFences[currentFrame])) {
currentImage = newImage.value();
VoxelUBO ubo{};
ubo.proj = ProjectionMatrix;
ubo.view = ViewMatrix;
ubo.fog = options.clear_color;
ubo.fog.a = FogDepth;
ubo.lightInv = LightInvDir;
commandCenter->startRecording(currentImage, pipeline->getRenderPass(),
getInfos().swapDetails.capabilities.currentExtent, options.clear_color, ViewMatrix, ProjectionMatrix);
getInfos().swapDetails.capabilities.currentExtent, ubo);
allocator->setTracyZone("Submit");
} else {
recreateSwapChain();
......@@ -423,10 +429,15 @@ void Renderer::beginFrame() {
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass() {
assert(currentImage < swapChain->getImageViews().size());
commandCenter->startWorldPass(currentImage, pipeline->getWorldPass());
commandCenter->recordModel(currentImage);
return [&](render::LodModel *const, glm::mat4, glm::vec4, float) {
return 0; //WorldPass->setup(this, model);
auto& pass = pipeline->getWorldPass();
commandCenter->startWorldPass(currentImage, pass);
return [&](render::LodModel *const rBuffer, glm::mat4 model, glm::vec4 sphere, float curv) {
auto buffer = dynamic_cast<render::vk::LodModel *const>(rBuffer);
UniqueCurvaturePush push{};
push.model = model;
push.sphereProj = sphere;
push.curvature = curv;
return commandCenter->recordModel(currentImage, pass, push, buffer);
};
}
......@@ -447,7 +458,7 @@ size_t Renderer::drawIndicatorCube(glm::mat4 model) {
}
void Renderer::postProcess() {
commandCenter->recordPostprocess(currentImage, pipeline->getSkyPass(), options.skybox, ViewMatrix, ProjectionMatrix);
commandCenter->recordPostprocess(currentImage, pipeline->getSkyPass(), options.skybox);
}
void Renderer::endFrame() {
......
......@@ -223,8 +223,8 @@ std::unique_ptr<TextureCube> TextureCube::LoadFromFiles(const std::string& prefi
std::unique_ptr<TextureArray> TextureArray::LoadFromFiles(const std::vector<std::string>& paths, const sampling& props) {
std::vector<std::vector<unsigned char>> datas;
std::vector<data_view> views;
datas.resize(1);
views.reserve(6);
datas.resize(paths.size());
views.reserve(paths.size());
auto header = [&] {
if (auto header = render::Image::Read(paths.at(0), datas.at(0))) {
views.push_back(datas.at(0));
......@@ -232,7 +232,6 @@ std::unique_ptr<TextureArray> TextureArray::LoadFromFiles(const std::vector<std:
}
FATAL("Cannot read first texture");
}();
datas.reserve(paths.size());
for (size_t i = 1; i < paths.size(); i++) {
if(!render::Image::Read(paths.at(i), datas.at(i)).has_value()) {
FATAL("Cannot read depth texture");
......
......@@ -73,6 +73,30 @@ class Model final: public render::Model, public ShortIndexedVertexBuffer {
public:
static std::unique_ptr<Model> Create(const Data &);
static VkVertexInputBindingDescription getBindingDescription() {
VkVertexInputBindingDescription description{};
description.binding = 0;
description.stride = sizeof(PackedVertexData);
description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return description;
}
static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R16G16B16_SFLOAT;
attributeDescriptions[0].offset = offsetof(PackedVertexData, PosMat[0]);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R16_UINT;
attributeDescriptions[1].offset = offsetof(PackedVertexData, PosMat[3]);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R16G16B16_SFLOAT;
attributeDescriptions[2].offset = offsetof(PackedVertexData, Nrm);
return attributeDescriptions;
}
protected:
Model(size_t size, VkBuffer vertex, VkBuffer index, memory::ptr mem):
ShortIndexedVertexBuffer(vertex, index, std::move(mem)), indexSize(size) { }
......@@ -85,6 +109,9 @@ public:
static void MakeDefault();
constexpr uint32_t getIndexStart() const { return getOffset(level); }
constexpr uint32_t getIndexSize() const { return getOffset(level+1) - getOffset(level); }
protected:
LodModel(size_t size, const std::vector<size_t>& off,
VkBuffer vertex, VkBuffer index, memory::ptr mem):
......@@ -95,7 +122,7 @@ protected:
}
};
struct UniformBufferObject {
struct ViewProjUBO {
alignas(16) glm::mat4 view;
alignas(16) glm::mat4 proj;
......@@ -109,9 +136,35 @@ struct UniformBufferObject {
return uboLayoutBinding;
}
};
struct VoxelUBO {
alignas(16) glm::mat4 view;
alignas(16) glm::mat4 proj;
alignas(16) glm::vec3 lightInv;
//NOTE: one "free" space
alignas(16) glm::vec4 fog;
static VkDescriptorSetLayoutBinding getLayoutBinding() {
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
uboLayoutBinding.pImmutableSamplers = nullptr;
return uboLayoutBinding;
}
};
struct ModelPush {
alignas(16) glm::mat4 model;
};
struct CurvaturePush {
alignas(16) glm::vec4 sphereProj;
alignas(4) float curvature;
};
struct UniqueCurvaturePush {
alignas(16) glm::mat4 model;
alignas(16) glm::vec4 sphereProj;
alignas(4) float curvature;
};
}
\ No newline at end of file
#pragma once
#include <glm/glm.hpp>
#include <vector>
#include <array>
#include <volk.h>
namespace buffer::vk {
struct VertexData {
glm::vec3 pos;
glm::vec3 color;
glm::vec2 uv;
static VkVertexInputBindingDescription getBindingDescription() {
VkVertexInputBindingDescription description{};
description.binding = 0;
description.stride = sizeof(VertexData);
description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return description;
}
static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[0].offset = offsetof(VertexData, pos);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[1].offset = offsetof(VertexData, color);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[2].offset = offsetof(VertexData, uv);
return attributeDescriptions;
}
};
const std::vector<VertexData> vertices = {
{{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
{{0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
{{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
{{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
{{0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
{{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}};
const std::vector<uint16_t> indices = {
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4
};
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment