WIP
This commit is contained in:
parent
07d12b3452
commit
2b33e97dfd
|
@ -30,7 +30,6 @@ void Client::run(server_handle* const localHandle) {
|
|||
auto world = world::client::Load(options.connection, localHandle, options.world, options.contouring);
|
||||
state.contouring = world->getContouring();
|
||||
|
||||
//TODO: loop
|
||||
do {
|
||||
window.startFrame();
|
||||
FrameMark;
|
||||
|
@ -131,9 +130,8 @@ void Client::run(server_handle* const localHandle) {
|
|||
{ // Chunks
|
||||
const auto pass = pipeline->beginWorldPass();
|
||||
const auto draw = [&](glm::mat4 model, render::LodModel *const buffer, const contouring::Abstract::area_info &area, const voxel_pos &pos) {
|
||||
pipeline->setCurvature(glm::vec4(pos, std::get<1>(area)), std::get<2>(area));
|
||||
reports.models_count++;
|
||||
reports.tris_count += pass(buffer, model);
|
||||
reports.tris_count += pass(buffer, model, glm::vec4(pos, std::get<1>(area)), std::get<2>(area));
|
||||
};
|
||||
if (options.culling > 0) {
|
||||
std::vector<glm::vec3> occlusion;
|
||||
|
@ -166,9 +164,9 @@ void Client::run(server_handle* const localHandle) {
|
|||
reports.models_count++;
|
||||
reports.tris_count += pipeline->drawIndicatorCube(model);
|
||||
}
|
||||
pipeline->endPass();
|
||||
|
||||
pipeline->postProcess();
|
||||
render::UI::Get()->render();
|
||||
pipeline->endFrame();
|
||||
}
|
||||
|
||||
{ // Swap buffers
|
||||
|
|
|
@ -64,13 +64,16 @@ public:
|
|||
/// Start new frame and setup
|
||||
virtual void beginFrame() = 0;
|
||||
/// Get started world program
|
||||
virtual std::function<size_t(render::LodModel *const, glm::mat4)> beginWorldPass() = 0;
|
||||
/// (vertex buffer, model matrix, sphereProj, curvature)
|
||||
virtual std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() = 0;
|
||||
/// Get started entity program
|
||||
virtual std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> beginEntityPass() = 0;
|
||||
/// Draw cube indicator
|
||||
virtual size_t drawIndicatorCube(glm::mat4 model) = 0;
|
||||
/// Apply postprocessing
|
||||
virtual void endPass() = 0;
|
||||
virtual void postProcess() = 0;
|
||||
/// Finalise frame
|
||||
virtual void endFrame() = 0;
|
||||
/// Swap displayed image
|
||||
virtual void swapBuffer(Window &) = 0;
|
||||
|
||||
|
@ -78,7 +81,6 @@ public:
|
|||
virtual void lookFrom(const Camera &) = 0;
|
||||
|
||||
virtual void setClearColor(glm::vec4) = 0;
|
||||
virtual void setCurvature(glm::vec4, float) = 0;
|
||||
virtual void reloadShaders(const passOptions &) = 0;
|
||||
virtual void reloadTextures(const std::string &, float mipMapLOD, float anisotropy) = 0;
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
using namespace render;
|
||||
|
||||
std::unique_ptr<Texture> (*Texture::loadFunc)(const std::string&, const sampling&) = nullptr;
|
||||
std::unique_ptr<TextureCube> (*TextureCube::loadFunc)(const std::array<std::string, 6>&, const Texture::sampling &) = nullptr;
|
||||
std::unique_ptr<TextureArray> (*TextureArray::loadFunc)(const std::vector<std::string>&, const Texture::sampling &) = nullptr;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -73,8 +73,9 @@ public:
|
|||
};
|
||||
struct requirement: properties {
|
||||
requirement(const properties& props, Layout layout, Usage usage, Aspect aspect,
|
||||
int samples = 1, bool optimal = true): properties(props), layout(layout),
|
||||
usage(usage), aspect(aspect), samples(samples), optimal(optimal)
|
||||
int samples = 1, uint32_t depth = 1, uint32_t layers = 1, bool optimal = true):
|
||||
properties(props), layout(layout), usage(usage), aspect(aspect), samples(samples),
|
||||
depth(depth), layers(layers), optimal(optimal)
|
||||
{
|
||||
assert(samples > 0 && (std::ceil(std::log2(samples)) == std::floor(std::log2(samples))) && "Samples must be pow2");
|
||||
}
|
||||
|
@ -83,10 +84,12 @@ public:
|
|||
Aspect aspect;
|
||||
//NOTE: matches VkSampleCountFlagBits
|
||||
int samples;
|
||||
uint32_t depth;
|
||||
uint32_t layers;
|
||||
bool optimal;
|
||||
|
||||
static requirement Texture(const properties &props) {
|
||||
return requirement(props, Layout::SHADER_READ_ONLY, Usage::SAMPLED, Aspect::COLOR); }
|
||||
static requirement Texture(const properties &props, bool cube = false, uint32_t arraySize = 1) {
|
||||
return requirement(props, Layout::SHADER_READ_ONLY, Usage::SAMPLED, Aspect::COLOR, 1, cube ? 6 : 1, arraySize); }
|
||||
};
|
||||
|
||||
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data);
|
||||
|
@ -120,4 +123,36 @@ public:
|
|||
protected:
|
||||
static std::unique_ptr<Texture> (*loadFunc)(const std::string&, const sampling&);
|
||||
};
|
||||
|
||||
/// Const 6 dept image (single textureCube) with sampler
|
||||
class TextureCube: public Image {
|
||||
public:
|
||||
/// Only supports dds files
|
||||
/// DXT3(BC2) DXT5(BC3)
|
||||
static _FORCE_INLINE_ std::unique_ptr<TextureCube> LoadFromFiles(const std::array<std::string, 6> &paths, const Texture::sampling &props) {
|
||||
assert(loadFunc != nullptr && "Uninitialized renderer");
|
||||
return loadFunc(paths, props);
|
||||
}
|
||||
|
||||
protected:
|
||||
static std::unique_ptr<TextureCube> (*loadFunc)(const std::array<std::string, 6>&, const Texture::sampling&);
|
||||
};
|
||||
|
||||
/// Const image array (textureArray) with sampler
|
||||
class TextureArray: public Image {
|
||||
public:
|
||||
/// Only supports dds files
|
||||
/// DXT3(BC2) DXT5(BC3)
|
||||
static _FORCE_INLINE_ std::unique_ptr<TextureArray> LoadFromFiles(const std::vector<std::string> &paths, const Texture::sampling &props) {
|
||||
assert(loadFunc != nullptr && "Uninitialized renderer");
|
||||
return loadFunc(paths, props);
|
||||
}
|
||||
|
||||
constexpr uint32_t getSize() const { return size; }
|
||||
|
||||
protected:
|
||||
TextureArray(uint32_t size): size(size) { }
|
||||
uint32_t size;
|
||||
static std::unique_ptr<TextureArray> (*loadFunc)(const std::vector<std::string>&, const Texture::sampling&);
|
||||
};
|
||||
}
|
|
@ -115,11 +115,11 @@ void Renderer::beginFrame() {
|
|||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
std::function<size_t(render::LodModel *const, glm::mat4)> Renderer::beginWorldPass() {
|
||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass() {
|
||||
WorldPass->useIt();
|
||||
WorldPass->start(this);
|
||||
return [&](render::LodModel *const buf, glm::mat4 model) {
|
||||
WorldPass->setup(this, model);
|
||||
return [&](render::LodModel *const buf, glm::mat4 model, glm::vec4 sph, float curv) {
|
||||
WorldPass->setup(model, sph, curv);
|
||||
return dynamic_cast<LodModel *const>(buf)->draw();
|
||||
};
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> Rend
|
|||
EntityPass->useIt();
|
||||
EntityPass->start(this);
|
||||
return [&](render::Model *const buf, const std::vector<glm::mat4> &models) {
|
||||
EntityPass->setup(this, models);
|
||||
EntityPass->setup(models);
|
||||
return dynamic_cast<Model *const>(buf)->drawInstanced(models.size());
|
||||
};
|
||||
}
|
||||
|
@ -139,11 +139,12 @@ size_t Renderer::drawIndicatorCube(glm::mat4 model) {
|
|||
return IndicatorCubeBuffer.draw();
|
||||
}
|
||||
|
||||
void Renderer::endPass() {
|
||||
void Renderer::postProcess() {
|
||||
if(SkyEnable) {
|
||||
SkyPass->draw(this);
|
||||
}
|
||||
}
|
||||
void Renderer::endFrame() { }
|
||||
|
||||
void Renderer::swapBuffer(Window& w) {
|
||||
TracyGpuZone("Swap");
|
||||
|
@ -188,7 +189,3 @@ void Renderer::setClearColor(glm::vec4 c) {
|
|||
FogColor = c;
|
||||
glClearColor(c.r, c.g, c.b, c.a);
|
||||
}
|
||||
void Renderer::setCurvature(glm::vec4 sp, float c) {
|
||||
SphereProj = sp;
|
||||
Curvature = c;
|
||||
}
|
|
@ -41,20 +41,14 @@ public:
|
|||
}
|
||||
|
||||
void beginFrame() override;
|
||||
std::function<size_t(render::LodModel *const, glm::mat4)> beginWorldPass() override;
|
||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() override;
|
||||
std::function<size_t(render::Model *const, const std::vector<glm::mat4>&)> beginEntityPass() override;
|
||||
size_t drawIndicatorCube(glm::mat4 model) override;
|
||||
void endPass() override;
|
||||
void postProcess() override;
|
||||
void endFrame() override;
|
||||
void swapBuffer(Window&) override;
|
||||
|
||||
void setClearColor(glm::vec4) override;
|
||||
void setCurvature(glm::vec4, float) override;
|
||||
glm::vec4 getSphereProj() const {
|
||||
return SphereProj;
|
||||
}
|
||||
float getCurvature() const {
|
||||
return Curvature;
|
||||
}
|
||||
|
||||
/// Apply camera matrices
|
||||
void lookFrom(const Camera&) override;
|
||||
|
@ -84,12 +78,6 @@ private:
|
|||
GLuint HOSAtlas;
|
||||
GLuint Skybox;
|
||||
|
||||
/// Sphere bending
|
||||
/// offset.xyz radius.w
|
||||
glm::vec4 SphereProj;
|
||||
/// Ratio between spherical and cartesian
|
||||
float Curvature;
|
||||
|
||||
/// Draw skybox
|
||||
bool SkyEnable;
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@ EntityProgram::EntityProgram(const EntityProgram::options &opts) : VoxelProgram(
|
|||
}
|
||||
EntityProgram::~EntityProgram() { }
|
||||
|
||||
void EntityProgram::setup(render::gl::Renderer *renderer, const std::vector<glm::mat4>& modelsMatrices) {
|
||||
void EntityProgram::setup(const std::vector<glm::mat4>& modelsMatrices) {
|
||||
setModels(&modelsMatrices[0][0][0], modelsMatrices.size());
|
||||
VoxelProgram::setup(renderer);
|
||||
VoxelProgram::setup(glm::vec4(0), 0);
|
||||
}
|
||||
|
||||
void EntityProgram::setModels(const GLfloat *matrices, size_t count) {
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace pass {
|
|||
|
||||
static constexpr auto LOCATION = 6;
|
||||
|
||||
void setup(render::gl::Renderer *, const std::vector<glm::mat4> &modelsMatrices);
|
||||
void setup(const std::vector<glm::mat4> &modelsMatrices);
|
||||
void disable();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -62,9 +62,9 @@ void VoxelProgram::start(render::gl::Renderer *renderer) {
|
|||
setView(&renderer->getViewMatrix()[0][0]);
|
||||
setProj(&renderer->getProjectionMatrix()[0][0]);
|
||||
}
|
||||
void VoxelProgram::setup(render::gl::Renderer *renderer) {
|
||||
setSphereProj(&renderer->getSphereProj()[0]);
|
||||
setCurvature(renderer->getCurvature());
|
||||
void VoxelProgram::setup(glm::vec4 sphereProj, float curvature) {
|
||||
setSphereProj(&sphereProj[0]);
|
||||
setCurvature(curvature);
|
||||
}
|
||||
|
||||
void VoxelProgram::setProj(const GLfloat *matrix) {
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace pass {
|
|||
void start(render::gl::Renderer *);
|
||||
|
||||
protected:
|
||||
void setup(render::gl::Renderer *);
|
||||
void setup(glm::vec4 sphereProj, float curvature);
|
||||
|
||||
std::string getName() const override;
|
||||
void setView(const GLfloat *matrix);
|
||||
|
|
|
@ -11,9 +11,9 @@ WorldProgram::WorldProgram(const WorldProgram::options& opts): VoxelProgram(opts
|
|||
|
||||
WorldProgram::~WorldProgram() { }
|
||||
|
||||
void WorldProgram::setup(render::gl::Renderer *renderer, glm::mat4 modelMatrix) {
|
||||
void WorldProgram::setup(glm::mat4 modelMatrix, glm::vec4 sphereProj, float curvature) {
|
||||
setModel(&modelMatrix[0][0]);
|
||||
VoxelProgram::setup(renderer);
|
||||
VoxelProgram::setup(sphereProj, curvature);
|
||||
}
|
||||
|
||||
void WorldProgram::setModel(const GLfloat *matrix) {
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace pass {
|
|||
WorldProgram(const options &opts);
|
||||
~WorldProgram();
|
||||
|
||||
void setup(render::gl::Renderer *, glm::mat4 modelMatrix);
|
||||
void setup(glm::mat4 modelMatrix, glm::vec4 sphereProj, float curvature);
|
||||
|
||||
protected:
|
||||
void setModel(const GLfloat *matrix);
|
||||
|
|
|
@ -195,7 +195,7 @@ void Allocator::copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize size) {
|
|||
|
||||
submitCmd(transferBuffer, transferQueue);
|
||||
}
|
||||
void Allocator::transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t mipLevels) {
|
||||
void Allocator::transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t mipLevels, uint32_t arrayLayers) {
|
||||
beginCmd(graphicsBuffer);
|
||||
|
||||
VkImageMemoryBarrier barrier{};
|
||||
|
@ -210,7 +210,7 @@ void Allocator::transitionImageLayout(VkImage image, VkFormat format, VkImageLay
|
|||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = mipLevels;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
barrier.subresourceRange.layerCount = arrayLayers;
|
||||
|
||||
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
@ -257,7 +257,7 @@ void Allocator::transitionImageLayout(VkImage image, VkFormat format, VkImageLay
|
|||
|
||||
submitCmd(graphicsBuffer, graphicsQueue);
|
||||
}
|
||||
void Allocator::copyBufferToImage(VkBuffer src, VkImage dest, uint32_t width, uint32_t height, uint32_t mipLevels) {
|
||||
void Allocator::copyBufferToImage(VkBuffer src, VkImage dest, uint32_t width, uint32_t height, uint32_t mipLevels, uint32_t depth, uint32_t arrayLayer) {
|
||||
|
||||
beginCmd(transferBuffer);
|
||||
|
||||
|
@ -266,11 +266,11 @@ void Allocator::copyBufferToImage(VkBuffer src, VkImage dest, uint32_t width, ui
|
|||
for (size_t i = 0; i < mipLevels; i++) {
|
||||
regions[i].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
regions[i].imageSubresource.mipLevel = i;
|
||||
regions[i].imageSubresource.baseArrayLayer = 0;
|
||||
regions[i].imageSubresource.baseArrayLayer = arrayLayer;
|
||||
regions[i].imageSubresource.layerCount = 1;
|
||||
|
||||
regions[i].imageOffset = {0, 0, 0};
|
||||
regions[i].imageExtent = {width >> i, height >> i, 1};
|
||||
regions[i].imageOffset = {0, 0, depth+0};
|
||||
regions[i].imageExtent = {width >> i, height >> i, depth+1};
|
||||
|
||||
regions[i].bufferOffset = offset;
|
||||
regions[i].bufferRowLength = std::max<uint32_t>(4, regions[i].imageExtent.width);
|
||||
|
|
|
@ -37,8 +37,8 @@ public:
|
|||
bool deallocate(const memory::area&);
|
||||
|
||||
void copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize size);
|
||||
void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t mipLevels);
|
||||
void copyBufferToImage(VkBuffer src, VkImage dst, uint32_t width, uint32_t height, uint32_t mipLevels = 1);
|
||||
void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t mipLevels, uint32_t arrayLayers);
|
||||
void copyBufferToImage(VkBuffer src, VkImage dst, uint32_t width, uint32_t height, uint32_t mipLevels = 1, uint32_t depth = 0, uint32_t arrayLayer = 0);
|
||||
|
||||
void setTracyZone(const char* name);
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ CommandCenter::~CommandCenter() {
|
|||
vkDestroyCommandPool(device, graphicsPool, ALLOC);
|
||||
}
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent, const renderOptions& opt) {
|
||||
void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent) {
|
||||
assert(freed);
|
||||
|
||||
if (colorSamples > 1) {
|
||||
|
@ -164,44 +164,6 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
|
|||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < graphicsBuffers.size(); i++) {
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
beginInfo.flags = 0;
|
||||
beginInfo.pInheritanceInfo = nullptr;
|
||||
|
||||
if (vkBeginCommandBuffer(graphicsBuffers[i], &beginInfo) != VK_SUCCESS) {
|
||||
FATAL("Failed to begin recording command buffer!");
|
||||
}
|
||||
|
||||
VkRenderPassBeginInfo renderPassInfo{};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassInfo.renderPass = pipe.getRenderPass();
|
||||
renderPassInfo.framebuffer = framebuffers[i];
|
||||
renderPassInfo.renderArea.offset = {0, 0};
|
||||
renderPassInfo.renderArea.extent = extent;
|
||||
|
||||
std::array<VkClearValue, 2> clearValues{};
|
||||
clearValues[0].color = {opt.clear_color.x, opt.clear_color.y, opt.clear_color.z, opt.clear_color.a};
|
||||
clearValues[1].depthStencil = {1.0f, 0};
|
||||
renderPassInfo.clearValueCount = clearValues.size();
|
||||
renderPassInfo.pClearValues = clearValues.data();
|
||||
|
||||
vkCmdBeginRenderPass(graphicsBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdBindPipeline(graphicsBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.getPipeline());
|
||||
VkBuffer vertexBuffers[] = {modelBuffer->getVertex()};
|
||||
VkDeviceSize offsets[] = {0};
|
||||
vkCmdBindVertexBuffers(graphicsBuffers[i], 0, 1, vertexBuffers, offsets);
|
||||
vkCmdBindIndexBuffer(graphicsBuffers[i], modelBuffer->getIndex(), 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdBindDescriptorSets(graphicsBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.getLayout(), 0, 1, &descriptorSets[i], 0, nullptr);
|
||||
vkCmdDrawIndexed(graphicsBuffers[i], static_cast<uint32_t>(buffer::vk::indices.size()), 1, 0, 0, 0);
|
||||
vkCmdEndRenderPass(graphicsBuffers[i]);
|
||||
|
||||
if (vkEndCommandBuffer(graphicsBuffers[i]) != VK_SUCCESS) {
|
||||
FATAL("Failed to record graphics buffer!");
|
||||
}
|
||||
}
|
||||
|
||||
proj = glm::perspectiveZO(glm::radians(45.0f), extent.width / (float) extent.height, 0.1f, 10.0f);
|
||||
proj[1][1] *= -1;
|
||||
|
||||
|
@ -226,22 +188,65 @@ void CommandCenter::free() {
|
|||
#include <chrono>
|
||||
#include <memory.h>
|
||||
|
||||
void CommandCenter::updateUBO(uint32_t idx) {
|
||||
void CommandCenter::startRecording(uint32_t idx) {
|
||||
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();
|
||||
buffer::vk::UniformBufferObject ubo{};
|
||||
time = 0.1;
|
||||
ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
ubo.proj = proj;
|
||||
uniformBuffers.write(idx, data_view(&ubo, sizeof(ubo)));
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
//TODO: reuse
|
||||
beginInfo.pInheritanceInfo = nullptr;
|
||||
|
||||
if (vkBeginCommandBuffer(graphicsBuffers[idx], &beginInfo) != VK_SUCCESS) {
|
||||
FATAL("Failed to begin recording command buffer!");
|
||||
}
|
||||
}
|
||||
|
||||
void CommandCenter::startWorldPass(uint32_t idx, const Pipeline &pipe, VkExtent2D extent, const glm::vec4& clear_color) {
|
||||
VkRenderPassBeginInfo renderPassInfo{};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassInfo.renderPass = pipe.getRenderPass();
|
||||
renderPassInfo.framebuffer = framebuffers[idx];
|
||||
renderPassInfo.renderArea.offset = {0, 0};
|
||||
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[1].depthStencil = {1.0f, 0};
|
||||
renderPassInfo.clearValueCount = clearValues.size();
|
||||
renderPassInfo.pClearValues = clearValues.data();
|
||||
|
||||
vkCmdBeginRenderPass(graphicsBuffers[idx], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdBindPipeline(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.getPipeline());
|
||||
vkCmdBindDescriptorSets(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.getLayout(), 0, 1, &descriptorSets[idx], 0, nullptr);
|
||||
}
|
||||
void CommandCenter::recordModel(uint32_t i) {
|
||||
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);
|
||||
}
|
||||
void CommandCenter::startEntityPass(uint32_t) { }
|
||||
void CommandCenter::recordPostprocess(uint32_t idx) {
|
||||
vkCmdEndRenderPass(graphicsBuffers[idx]);
|
||||
}
|
||||
|
||||
void CommandCenter::submitGraphics(uint32_t idx, VkSemaphore waitSemaphore, VkSemaphore signalSemaphore, VkFence submittedFence) {
|
||||
assert(!freed);
|
||||
|
||||
if (vkEndCommandBuffer(graphicsBuffers[idx]) != VK_SUCCESS) {
|
||||
FATAL("Failed to record graphics buffer!");
|
||||
}
|
||||
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <glm/mat4x4.hpp>
|
||||
#include "api/Buffers.hpp"
|
||||
#include "api/Images.hpp"
|
||||
#include "api/Models.hpp"
|
||||
|
||||
namespace render::vk {
|
||||
class SwapChain;
|
||||
|
@ -15,10 +16,15 @@ public:
|
|||
CommandCenter(VkDevice, const PhysicalDeviceInfo&, const renderOptions&);
|
||||
~CommandCenter();
|
||||
|
||||
void updateUBO(uint32_t idx);
|
||||
void startRecording(uint32_t idx);
|
||||
void startWorldPass(uint32_t idx, const Pipeline &, VkExtent2D, const glm::vec4 &clear);
|
||||
void recordModel(uint32_t idx);
|
||||
void startEntityPass(uint32_t idx);
|
||||
//void recordModel(uint32_t idx);
|
||||
void recordPostprocess(uint32_t idx);
|
||||
void submitGraphics(uint32_t, VkSemaphore, VkSemaphore, VkFence);
|
||||
|
||||
void allocate(const std::vector<VkImageView>&, const Pipeline&, VkExtent2D, const renderOptions&);
|
||||
void allocate(const std::vector<VkImageView>&, const Pipeline&, VkExtent2D);
|
||||
void free();
|
||||
|
||||
private:
|
||||
|
@ -43,6 +49,9 @@ private:
|
|||
|
||||
std::unique_ptr<Texture> sampleTexture;
|
||||
|
||||
std::unique_ptr<TextureCube> skyboxTexture;
|
||||
std::unique_ptr<Shape> skyCubeBuffer;
|
||||
|
||||
glm::mat4 proj;
|
||||
BufferGroup uniformBuffers;
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ Renderer::Renderer(VkInstance instance, VkDevice device, const PhysicalDeviceInf
|
|||
swapChain = std::make_unique<SwapChain>(device, getInfos());
|
||||
pipeline = std::make_unique<Pipeline>(device, getInfos(), options);
|
||||
commandCenter = std::make_unique<CommandCenter>(device, getInfos(), options);
|
||||
commandCenter->allocate(swapChain->getImageViews(), *pipeline.get(), getInfos().swapDetails.capabilities.currentExtent, options);
|
||||
commandCenter->allocate(swapChain->getImageViews(), *pipeline.get(), getInfos().swapDetails.capabilities.currentExtent);
|
||||
|
||||
{
|
||||
imageAvailableSemaphores.resize(opt.inFlightFrames);
|
||||
|
@ -105,7 +105,7 @@ void Renderer::recreateSwapChain() {
|
|||
set_current_extent(physicalInfo->swapDetails.capabilities, physicalInfo->window);
|
||||
swapChain = std::make_unique<SwapChain>(device, getInfos());
|
||||
pipeline = std::make_unique<Pipeline>(device, getInfos(), options);
|
||||
commandCenter->allocate(swapChain->getImageViews(), *pipeline.get(), getInfos().swapDetails.capabilities.currentExtent, options);
|
||||
commandCenter->allocate(swapChain->getImageViews(), *pipeline.get(), getInfos().swapDetails.capabilities.currentExtent);
|
||||
}
|
||||
void Renderer::destroySwapChain() {
|
||||
commandCenter->free();
|
||||
|
@ -409,6 +409,7 @@ void Renderer::beginFrame() {
|
|||
|
||||
if (auto newImage = swapChain->acquireNextImage(imageAvailableSemaphores[currentFrame], inFlightFences[currentFrame])) {
|
||||
currentImage = newImage.value();
|
||||
commandCenter->startRecording(currentImage);
|
||||
allocator->setTracyZone("Submit");
|
||||
} else {
|
||||
recreateSwapChain();
|
||||
|
@ -416,37 +417,40 @@ void Renderer::beginFrame() {
|
|||
}
|
||||
}
|
||||
|
||||
std::function<size_t(render::LodModel *const, glm::mat4)> Renderer::beginWorldPass() {
|
||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass() {
|
||||
assert(currentImage < swapChain->getImageViews().size());
|
||||
|
||||
commandCenter->updateUBO(currentImage);
|
||||
commandCenter->submitGraphics(currentImage, imageAvailableSemaphores[currentFrame],
|
||||
renderFinishedSemaphores[currentFrame], inFlightFences[currentFrame]);
|
||||
/*WorldPass->useIt();
|
||||
WorldPass->start(this);*/
|
||||
return [&](render::LodModel *const, glm::mat4) {
|
||||
commandCenter->startWorldPass(currentImage, *pipeline.get(),
|
||||
getInfos().swapDetails.capabilities.currentExtent, options.clear_color);
|
||||
commandCenter->recordModel(currentImage);
|
||||
return [&](render::LodModel *const, glm::mat4, glm::vec4, float) {
|
||||
return 0; //WorldPass->setup(this, model);
|
||||
};
|
||||
}
|
||||
|
||||
std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> Renderer::beginEntityPass() {
|
||||
/*EntityPass->useIt();
|
||||
EntityPass->start(this);*/
|
||||
assert(currentImage < swapChain->getImageViews().size());
|
||||
|
||||
commandCenter->startEntityPass(currentImage);
|
||||
return [&](render::Model *const, const std::vector<glm::mat4>&) {
|
||||
return 0; //EntityPass->setup(this, models);
|
||||
};
|
||||
}
|
||||
|
||||
size_t Renderer::drawIndicatorCube(glm::mat4) {
|
||||
/*IndicatorPass->useIt();
|
||||
return IndicatorCubeBuffer.draw(IndicatorPass->setup(this, model));*/
|
||||
assert(currentImage < swapChain->getImageViews().size());
|
||||
|
||||
//commandCenter->drawIndicator(model);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Renderer::endPass() {
|
||||
/*if(SkyEnable) {
|
||||
SkyPass->draw(this);
|
||||
}*/
|
||||
void Renderer::postProcess() {
|
||||
commandCenter->recordPostprocess(currentImage/*, options.skybox*/);
|
||||
}
|
||||
|
||||
void Renderer::endFrame() {
|
||||
commandCenter->submitGraphics(currentImage, imageAvailableSemaphores[currentFrame],
|
||||
renderFinishedSemaphores[currentFrame], inFlightFences[currentFrame]);
|
||||
}
|
||||
|
||||
void Renderer::swapBuffer(Window&) {
|
||||
|
@ -477,11 +481,6 @@ void Renderer::lookFrom(const Camera&) {
|
|||
FogDepth = camera.getDepth();*/
|
||||
}
|
||||
|
||||
void Renderer::setClearColor(glm::vec4) {
|
||||
/*FogColor = c;
|
||||
glClearColor(c.r, c.g, c.b, c.a);*/
|
||||
}
|
||||
void Renderer::setCurvature(glm::vec4, float) {
|
||||
/*SphereProj = sp;
|
||||
Curvature = c;*/
|
||||
void Renderer::setClearColor(glm::vec4 c) {
|
||||
options.clear_color = c;
|
||||
}
|
|
@ -20,14 +20,14 @@ public:
|
|||
static _FORCE_INLINE_ Renderer *Get() { return static_cast<Renderer*>(render::Renderer::Get()); }
|
||||
|
||||
void beginFrame() override;
|
||||
std::function<size_t(render::LodModel *const, glm::mat4)> beginWorldPass() override;
|
||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() override;
|
||||
std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> beginEntityPass() override;
|
||||
size_t drawIndicatorCube(glm::mat4 model) override;
|
||||
void endPass() override;
|
||||
void swapBuffer(Window&) override;
|
||||
void postProcess() override;
|
||||
void endFrame() override;
|
||||
void swapBuffer(Window &) override;
|
||||
|
||||
void setClearColor(glm::vec4) override;
|
||||
void setCurvature(glm::vec4, float) override;
|
||||
|
||||
/// Apply camera matrices
|
||||
void lookFrom(const Camera &) override;
|
||||
|
|
|
@ -9,7 +9,7 @@ Buffer::~Buffer() {
|
|||
//NOTE: memory_ptr self destroy
|
||||
}
|
||||
|
||||
memory::ptr createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, const render::data_view view, Buffer::info &out) {
|
||||
memory::ptr render::vk::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, const render::data_view view, Buffer::info &out) {
|
||||
auto alloc = Allocator::GetDefault();
|
||||
auto device = alloc->getDevice();
|
||||
|
||||
|
|
|
@ -88,4 +88,5 @@ private:
|
|||
memory::ptr memory;
|
||||
};
|
||||
|
||||
memory::ptr createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, const render::data_view view, Buffer::info &out);
|
||||
}
|
|
@ -13,18 +13,18 @@ Texture::~Texture() {
|
|||
vkDestroySampler(Allocator::GetDefault()->getDevice(), sampler, ALLOC);
|
||||
}
|
||||
|
||||
memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags properties, const render::data_view data, Image::info& out) {
|
||||
memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags properties, const std::vector<render::data_view>& datas, Image::info& out) {
|
||||
auto alloc = Allocator::GetDefault();
|
||||
auto device = alloc->getDevice();
|
||||
|
||||
VkImageCreateInfo info{};
|
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
info.imageType = VK_IMAGE_TYPE_2D;
|
||||
info.imageType = req.depth > 1 ? VK_IMAGE_TYPE_3D : VK_IMAGE_TYPE_2D;
|
||||
info.extent.width = req.size.width;
|
||||
info.extent.height = req.size.height;
|
||||
info.extent.depth = 1;
|
||||
info.extent.depth = req.depth;
|
||||
info.mipLevels = req.mipmapLevels;
|
||||
info.arrayLayers = 1;
|
||||
info.arrayLayers = req.layers;
|
||||
info.format = static_cast<VkFormat>(req.format);
|
||||
info.tiling = req.optimal ? VK_IMAGE_TILING_OPTIMAL : VK_IMAGE_TILING_LINEAR;
|
||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
@ -32,7 +32,7 @@ memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags pro
|
|||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.samples = static_cast<VkSampleCountFlagBits>(req.samples);
|
||||
info.flags = 0;
|
||||
if (data) {
|
||||
if (!datas.empty()) {
|
||||
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
}
|
||||
|
||||
|
@ -51,29 +51,43 @@ memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags pro
|
|||
return memory::GetNull();
|
||||
}
|
||||
|
||||
if (data) {
|
||||
if(auto staging = WritableBuffer::Create(data.size)) {
|
||||
staging->write(data, 0);
|
||||
alloc->transitionImageLayout(out.ref, info.format, info.initialLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, req.mipmapLevels);
|
||||
if (!datas.empty()) {
|
||||
const auto maxSize = [&] {
|
||||
size_t max = 0;
|
||||
for (auto& data: datas)
|
||||
max = std::max(max, data.size);
|
||||
return max;
|
||||
}();
|
||||
if(auto staging = WritableBuffer::Create(maxSize)) {
|
||||
alloc->transitionImageLayout(out.ref, info.format, info.initialLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, req.mipmapLevels, req.layers);
|
||||
info.initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
alloc->copyBufferToImage(staging->getRef(), out.ref, info.extent.width, info.extent.height, req.mipmapLevels);
|
||||
size_t i = 0;
|
||||
for (size_t layer = 0; layer < req.layers && i < datas.size(); layer++) {
|
||||
for (size_t depth = 0; depth < req.depth && i < datas.size(); depth++) {
|
||||
if(datas[i].isUsable()) {
|
||||
staging->write(datas[i], 0);
|
||||
alloc->copyBufferToImage(staging->getRef(), out.ref, info.extent.width, info.extent.height, req.mipmapLevels, depth, layer);
|
||||
}
|
||||
i++;
|
||||
}}
|
||||
} else {
|
||||
LOG_E("Cannot allocate staging memory");
|
||||
return memory::GetNull();
|
||||
}
|
||||
}
|
||||
alloc->transitionImageLayout(out.ref, info.format, info.initialLayout, static_cast<VkImageLayout>(req.layout), req.mipmapLevels);
|
||||
alloc->transitionImageLayout(out.ref, info.format, info.initialLayout, static_cast<VkImageLayout>(req.layout), req.mipmapLevels, req.layers);
|
||||
|
||||
VkImageViewCreateInfo viewInfo{};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.image = out.ref;
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.viewType = req.layers > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY :
|
||||
(req.depth == 6 ? VK_IMAGE_VIEW_TYPE_CUBE : VK_IMAGE_VIEW_TYPE_2D);
|
||||
viewInfo.format = static_cast<VkFormat>(req.format);
|
||||
viewInfo.subresourceRange.aspectMask = static_cast<VkImageAspectFlags>(req.aspect);
|
||||
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewInfo.subresourceRange.levelCount = req.mipmapLevels;
|
||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
viewInfo.subresourceRange.layerCount = req.layers;
|
||||
|
||||
if (vkCreateImageView(device, &viewInfo, ALLOC, &out.view) != VK_SUCCESS) {
|
||||
LOG_E("Failed to create texture image view!");
|
||||
|
@ -81,35 +95,17 @@ memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags pro
|
|||
}
|
||||
return memory;
|
||||
}
|
||||
//TODO: createImages
|
||||
|
||||
std::unique_ptr<Image> Image::Create(const requirement & req) {
|
||||
vk::Image::info img;
|
||||
auto mem = createImage(req, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, data_view(), img);
|
||||
auto mem = createImage(req, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, {}, img);
|
||||
if(!mem) {
|
||||
FATAL("Cannot create texture image");
|
||||
}
|
||||
return std::unique_ptr<Image>(new Image(img.ref, img.view, std::move(mem)));
|
||||
}
|
||||
|
||||
std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sampling& props) {
|
||||
auto device = Allocator::GetDefault()->getDevice();
|
||||
|
||||
std::vector<unsigned char> data;
|
||||
auto header = [&] {
|
||||
if (auto header = render::Image::Read(path, data)) {
|
||||
return header.value();
|
||||
}
|
||||
FATAL("Cannot read texture");
|
||||
}();
|
||||
|
||||
vk::Image::info img;
|
||||
auto mem = createImage(requirement::Texture(header),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, data, img);
|
||||
if(!mem) {
|
||||
FATAL("Cannot create texture image");
|
||||
}
|
||||
|
||||
VkSampler createSampler(const Texture::sampling& props, uint32_t mipmapLevels) {
|
||||
VkSamplerCreateInfo samplerInfo{};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.magFilter = props.magLinear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
|
@ -138,16 +134,94 @@ std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sa
|
|||
samplerInfo.mipmapMode = props.minLinear ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
samplerInfo.mipLodBias = 0.0f; //TODO:
|
||||
samplerInfo.minLod = 0.0f;
|
||||
samplerInfo.maxLod = props.mipmap ? header.mipmapLevels : 0.0f;
|
||||
samplerInfo.maxLod = props.mipmap ? mipmapLevels : 0.0f;
|
||||
|
||||
if (props.mipmap && header.mipmapLevels <= 1) {
|
||||
if (props.mipmap && mipmapLevels <= 1) {
|
||||
LOG_D("Sampler requires mipmap but image does not");
|
||||
}
|
||||
|
||||
VkSampler sampler;
|
||||
if (vkCreateSampler(device, &samplerInfo, ALLOC, &sampler) != VK_SUCCESS) {
|
||||
if (vkCreateSampler(Allocator::GetDefault()->getDevice(), &samplerInfo, ALLOC, &sampler) != VK_SUCCESS) {
|
||||
FATAL("Failed to create texture sampler!");
|
||||
}
|
||||
return sampler;
|
||||
}
|
||||
|
||||
return std::unique_ptr<Texture>(new Texture(sampler, img.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, img.ref, std::move(mem)));
|
||||
std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sampling& props) {
|
||||
std::vector<unsigned char> data;
|
||||
auto header = [&] {
|
||||
if (auto header = render::Image::Read(path, data)) {
|
||||
return header.value();
|
||||
}
|
||||
FATAL("Cannot read texture");
|
||||
}();
|
||||
|
||||
vk::Image::info img;
|
||||
auto mem = createImage(requirement::Texture(header),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, {data}, img);
|
||||
if(!mem) {
|
||||
FATAL("Cannot create texture image");
|
||||
}
|
||||
|
||||
return std::unique_ptr<Texture>(new Texture(createSampler(props, header.mipmapLevels), img.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, img.ref, std::move(mem)));
|
||||
}
|
||||
|
||||
std::unique_ptr<TextureCube> TextureCube::LoadFromFiles(const std::array<std::string, 6>& paths, const sampling& props) {
|
||||
std::vector<std::vector<unsigned char>> datas;
|
||||
std::vector<data_view> views;
|
||||
views.reserve(6);
|
||||
datas.resize(1);
|
||||
auto header = [&] {
|
||||
if (auto header = render::Image::Read(paths.at(0), datas.at(0))) {
|
||||
views.push_back(datas.at(0));
|
||||
return header.value();
|
||||
}
|
||||
FATAL("Cannot read first texture");
|
||||
}();
|
||||
datas.resize(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");
|
||||
}
|
||||
views.push_back(datas.at(i));
|
||||
}
|
||||
|
||||
vk::Image::info img;
|
||||
auto mem = createImage(requirement::Texture(header, true),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, views, img);
|
||||
if(!mem) {
|
||||
FATAL("Cannot create texture cube image");
|
||||
}
|
||||
|
||||
return std::unique_ptr<TextureCube>(new TextureCube(createSampler(props, header.mipmapLevels), img.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, img.ref, std::move(mem)));
|
||||
}
|
||||
|
||||
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);
|
||||
auto header = [&] {
|
||||
if (auto header = render::Image::Read(paths.at(0), datas.at(0))) {
|
||||
views.push_back(datas.at(0));
|
||||
return header.value();
|
||||
}
|
||||
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");
|
||||
}
|
||||
views.push_back(datas.at(i));
|
||||
}
|
||||
|
||||
vk::Image::info img;
|
||||
auto mem = createImage(requirement::Texture(header, false, paths.size()),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, views, img);
|
||||
if(!mem) {
|
||||
FATAL("Cannot create texture cube image");
|
||||
}
|
||||
|
||||
return std::unique_ptr<TextureArray>(new TextureArray(paths.size(), createSampler(props, header.mipmapLevels), img.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, img.ref, std::move(mem)));
|
||||
}
|
|
@ -44,4 +44,22 @@ protected:
|
|||
const VkDescriptorImageInfo descriptor;
|
||||
};
|
||||
|
||||
class TextureCube: public render::TextureCube, Texture {
|
||||
public:
|
||||
static std::unique_ptr<TextureCube> LoadFromFiles(const std::array<std::string, 6>&, const sampling&);
|
||||
|
||||
protected:
|
||||
TextureCube(VkSampler sampler, VkImageView view, VkImageLayout layout, VkImage ref, memory::ptr memory):
|
||||
Texture(sampler, view, layout, ref, std::move(memory)) { }
|
||||
};
|
||||
|
||||
class TextureArray: public render::TextureArray, Texture {
|
||||
public:
|
||||
static std::unique_ptr<TextureArray> LoadFromFiles(const std::vector<std::string>&, const sampling&);
|
||||
|
||||
protected:
|
||||
TextureArray(uint32_t size, VkSampler sampler, VkImageView view, VkImageLayout layout, VkImage ref, memory::ptr memory):
|
||||
render::TextureArray(size), Texture(sampler, view, layout, ref, std::move(memory)) { }
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include "Models.hpp"
|
||||
|
||||
using namespace render::vk;
|
||||
|
||||
std::unique_ptr<Shape> Shape::Create(const std::vector<glm::vec3>& vertices) {
|
||||
vk::Buffer::info tmp;
|
||||
data_view view(vertices);
|
||||
auto mem = createBuffer(view.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, view, tmp);
|
||||
return std::unique_ptr<Shape>(new Shape(tmp.ref, std::move(mem), vertices.size()));
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../api/Models.hpp"
|
||||
#include "Buffers.hpp"
|
||||
|
||||
namespace render::vk {
|
||||
|
||||
/// Positions only buffer
|
||||
class Shape final: Buffer {
|
||||
public:
|
||||
const size_t size;
|
||||
|
||||
static std::unique_ptr<Shape> Create(const std::vector<glm::vec3>&);
|
||||
|
||||
protected:
|
||||
Shape(VkBuffer ref, memory::ptr mem, size_t size):
|
||||
Buffer(ref, std::move(mem)), size(size) { }
|
||||
};
|
||||
|
||||
/*class Indicator final: public render::Indicator {
|
||||
public:
|
||||
Indicator(const std::vector<glm::vec3>&, const std::vector<glm::vec4>&);
|
||||
~Indicator();
|
||||
|
||||
size_t draw();
|
||||
size_t drawInstanced(size_t count);
|
||||
|
||||
private:
|
||||
size_t size;
|
||||
GLuint vertexBufferId;
|
||||
GLuint colorBufferId;
|
||||
|
||||
void enableAttribs();
|
||||
void disableAttribs();
|
||||
};
|
||||
|
||||
class Model final: public render::Model {
|
||||
public:
|
||||
Model(const Data&);
|
||||
~Model();
|
||||
|
||||
size_t draw();
|
||||
size_t drawInstanced(size_t count);
|
||||
|
||||
private:
|
||||
size_t indexSize;
|
||||
GLuint vertexBufferId;
|
||||
GLuint indexBufferId;
|
||||
};
|
||||
class LodModel final: public render::LodModel {
|
||||
public:
|
||||
LodModel(const LodData&);
|
||||
~LodModel();
|
||||
|
||||
static void MakeDefault();
|
||||
|
||||
size_t draw();
|
||||
size_t drawInstanced(size_t count);
|
||||
|
||||
private:
|
||||
GLuint vertexBufferId;
|
||||
GLuint indexBufferId;
|
||||
};*/
|
||||
|
||||
}
|
Loading…
Reference in New Issue