moving files to better dirs
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
#include "resources/mesh.hpp"
|
||||
|
||||
#include <sophia/util/assert.hpp>
|
||||
#include <sophia/util/logger.hpp>
|
||||
|
||||
namespace sophia {
|
||||
|
||||
std::vector<vk::VertexInputBindingDescription>
|
||||
Mesh::Vertex::getBindingDescriptions() {
|
||||
std::vector<vk::VertexInputBindingDescription> bindingDescriptions(1);
|
||||
bindingDescriptions[0].binding = 0;
|
||||
bindingDescriptions[0].stride = sizeof(Vertex);
|
||||
bindingDescriptions[0].inputRate = vk::VertexInputRate::eVertex;
|
||||
|
||||
return bindingDescriptions;
|
||||
}
|
||||
|
||||
std::vector<vk::VertexInputAttributeDescription>
|
||||
Mesh::Vertex::getAttributeDescriptions() {
|
||||
std::vector<vk::VertexInputAttributeDescription> attributeDescriptions{};
|
||||
|
||||
attributeDescriptions.push_back(
|
||||
{0, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, position)});
|
||||
attributeDescriptions.push_back(
|
||||
{1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color)});
|
||||
// attributeDescriptions.push_back(
|
||||
// {2, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, normal)});
|
||||
// attributeDescriptions.push_back(
|
||||
// {3, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, uv)});
|
||||
|
||||
return attributeDescriptions;
|
||||
}
|
||||
|
||||
Mesh::Mesh(Device& device, const Builder& builder) : device{device} {
|
||||
createVertexBuffers(builder.vertices);
|
||||
createIndexBuffers(builder.indices);
|
||||
}
|
||||
|
||||
Mesh::~Mesh() = default;
|
||||
|
||||
void Mesh::bind(vk::CommandBuffer commandBuffer) const {
|
||||
vk::Buffer buffers[] = {this->vertexBuffer->getBuffer()};
|
||||
vk::DeviceSize offset[] = {0};
|
||||
commandBuffer.bindVertexBuffers(0, 1, buffers, offset);
|
||||
|
||||
if (this->hasIndexBuffer) {
|
||||
commandBuffer.bindIndexBuffer(this->indexBuffer->getBuffer(), 0,
|
||||
vk::IndexType::eUint32);
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::draw(vk::CommandBuffer commandBuffer) const {
|
||||
if (this->hasIndexBuffer) {
|
||||
commandBuffer.drawIndexed(this->indexCount, 1, 0, 0, 0);
|
||||
} else {
|
||||
commandBuffer.draw(this->vertexCount, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::createVertexBuffers(const std::vector<Vertex>& vertices) {
|
||||
this->vertexCount = static_cast<u32>(vertices.size());
|
||||
SOPHIA_ASSERT(this->vertexCount >= 3, "vertex count must be at least 3");
|
||||
|
||||
vk::DeviceSize bufferSize = sizeof(vertices[0]) * this->vertexCount;
|
||||
|
||||
u32 vertexSize = sizeof(vertices[0]);
|
||||
|
||||
Buffer stagingBuffer{
|
||||
this->device,
|
||||
vertexSize,
|
||||
vertexCount,
|
||||
vk::BufferUsageFlagBits::eTransferSrc,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent,
|
||||
};
|
||||
|
||||
stagingBuffer.map();
|
||||
stagingBuffer.writeToBuffer((void*)vertices.data());
|
||||
|
||||
vertexBuffer =
|
||||
std::make_unique<Buffer>(this->device, vertexSize, vertexCount,
|
||||
vk::BufferUsageFlagBits::eTransferDst |
|
||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||
vk::MemoryPropertyFlagBits::eDeviceLocal);
|
||||
|
||||
this->device.copyBuffer(stagingBuffer.getBuffer(),
|
||||
this->vertexBuffer->getBuffer(), bufferSize);
|
||||
}
|
||||
|
||||
void Mesh::createIndexBuffers(const std::vector<u32>& indicies) {
|
||||
this->indexCount = static_cast<u32>(indicies.size());
|
||||
this->hasIndexBuffer = this->indexCount > 0;
|
||||
|
||||
if (!this->hasIndexBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
vk::DeviceSize bufferSize = sizeof(indicies[0]) * this->indexCount;
|
||||
|
||||
u32 indexSize = sizeof(indicies[0]);
|
||||
|
||||
Buffer stagingBuffer{
|
||||
this->device,
|
||||
indexSize,
|
||||
indexCount,
|
||||
vk::BufferUsageFlagBits::eTransferSrc,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent,
|
||||
};
|
||||
|
||||
stagingBuffer.map();
|
||||
stagingBuffer.writeToBuffer((void*)indicies.data());
|
||||
|
||||
indexBuffer =
|
||||
std::make_unique<Buffer>(this->device, indexSize, indexCount,
|
||||
vk::BufferUsageFlagBits::eTransferDst |
|
||||
vk::BufferUsageFlagBits::eIndexBuffer,
|
||||
vk::MemoryPropertyFlagBits::eDeviceLocal);
|
||||
|
||||
this->device.copyBuffer(stagingBuffer.getBuffer(),
|
||||
this->indexBuffer->getBuffer(), bufferSize);
|
||||
}
|
||||
|
||||
} // namespace sophia
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <sophia/handles.hpp>
|
||||
#include <sophia/types.hpp>
|
||||
#include <vector>
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
namespace sophia {
|
||||
|
||||
class Mesh {
|
||||
public:
|
||||
using HandleType = MeshHandle;
|
||||
|
||||
struct Vertex {
|
||||
glm::vec2 position{};
|
||||
glm::vec3 color{};
|
||||
// glm::vec3 normal{};
|
||||
// glm::vec2 uv{};
|
||||
|
||||
static std::vector<vk::VertexInputBindingDescription>
|
||||
getBindingDescriptions();
|
||||
static std::vector<vk::VertexInputAttributeDescription>
|
||||
getAttributeDescriptions();
|
||||
|
||||
// bool operator==(const Vertex& other) const {
|
||||
// return position == other.position && color == other.color;
|
||||
// }
|
||||
};
|
||||
|
||||
struct Builder {
|
||||
std::vector<Vertex> vertices{};
|
||||
std::vector<uint32_t> indices{};
|
||||
|
||||
// void loadModel(const std::string& filepath);
|
||||
};
|
||||
|
||||
Mesh(Device& device, const Mesh::Builder& builder);
|
||||
~Mesh();
|
||||
|
||||
Mesh(const Mesh&) = delete;
|
||||
Mesh& operator=(const Mesh&) = delete;
|
||||
|
||||
// static std::unique_ptr<Mesh> createMeshFromFile(
|
||||
// Device& device, const std::string& filepath);
|
||||
|
||||
void bind(vk::CommandBuffer commandBuffer) const;
|
||||
void draw(vk::CommandBuffer commandBuffer) const;
|
||||
|
||||
private:
|
||||
void createVertexBuffers(const std::vector<Vertex>& vertices);
|
||||
void createIndexBuffers(const std::vector<u32>& indices);
|
||||
|
||||
Device& device;
|
||||
|
||||
std::unique_ptr<Buffer> vertexBuffer;
|
||||
u32 vertexCount;
|
||||
|
||||
bool hasIndexBuffer = false;
|
||||
std::unique_ptr<Buffer> indexBuffer;
|
||||
u32 indexCount;
|
||||
};
|
||||
|
||||
} // namespace sophia
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <sophia/util/pool.hpp>
|
||||
|
||||
#include "device.hpp"
|
||||
#include "render_target.hpp"
|
||||
#include "resources/render_target.hpp"
|
||||
|
||||
namespace sophia {
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "resources/render_target.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace sophia {
|
||||
|
||||
RenderTarget::RenderTarget(Device& device, vk::Format format, u32 width,
|
||||
u32 height)
|
||||
: device{device}, format{format} {
|
||||
create(std::max(width, 1u), std::max(height, 1u));
|
||||
}
|
||||
|
||||
RenderTarget::~RenderTarget() { destroy(); }
|
||||
|
||||
vk::Extent2D RenderTarget::getExtent() const {
|
||||
vk::Extent3D extent = this->image->getExtent();
|
||||
return {extent.width, extent.height};
|
||||
}
|
||||
|
||||
void RenderTarget::requestResize(u32 width, u32 height) {
|
||||
this->pendingExtent = vk::Extent2D{std::max(width, 1u), std::max(height, 1u)};
|
||||
}
|
||||
|
||||
void RenderTarget::applyPendingResize() {
|
||||
if (!this->pendingExtent) {
|
||||
return;
|
||||
}
|
||||
|
||||
vk::Extent2D extent = *this->pendingExtent;
|
||||
this->pendingExtent.reset();
|
||||
if (extent == getExtent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Earlier frames may still be sampling the old image (e.g. through the UI).
|
||||
this->device.waitIdle();
|
||||
destroy();
|
||||
create(extent.width, extent.height);
|
||||
}
|
||||
|
||||
void RenderTarget::create(u32 width, u32 height) {
|
||||
this->image = Image::Builder(this->device)
|
||||
.setExtent(width, height)
|
||||
.setFormat(this->format)
|
||||
.asColorAttachment()
|
||||
.withView()
|
||||
.build();
|
||||
}
|
||||
|
||||
void RenderTarget::destroy() { this->image.reset(); }
|
||||
|
||||
} // namespace sophia
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <sophia/types.hpp>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "device.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
namespace sophia {
|
||||
|
||||
/**
|
||||
* A place rendering can go. Currently always backed by an offscreen color
|
||||
* image.
|
||||
*
|
||||
* Owned by the ResourceRegistry and addressed through a RenderTargetHandle.
|
||||
*/
|
||||
class RenderTarget {
|
||||
public:
|
||||
RenderTarget(Device& device, vk::Format format, u32 width, u32 height);
|
||||
~RenderTarget();
|
||||
|
||||
RenderTarget(const RenderTarget&) = delete;
|
||||
RenderTarget& operator=(const RenderTarget&) = delete;
|
||||
|
||||
Image& getImage() const { return *this->image; }
|
||||
|
||||
vk::Extent2D getExtent() const;
|
||||
|
||||
void requestResize(u32 width, u32 height);
|
||||
|
||||
/**
|
||||
* Applies a pending resize. Waits for the GPU, so it must run before any of
|
||||
* the frame's work (or any UI reference to the image) is recorded.
|
||||
*/
|
||||
void applyPendingResize();
|
||||
|
||||
private:
|
||||
void create(u32 width, u32 height);
|
||||
void destroy();
|
||||
|
||||
Device& device;
|
||||
vk::Format format;
|
||||
|
||||
std::unique_ptr<Image> image;
|
||||
|
||||
std::optional<vk::Extent2D> pendingExtent;
|
||||
};
|
||||
|
||||
} // namespace sophia
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <sophia/util/pool.hpp>
|
||||
|
||||
#include "device.hpp"
|
||||
#include "mesh.hpp"
|
||||
#include "resources/mesh.hpp"
|
||||
#include "resources/pools/render_target_pool.hpp"
|
||||
|
||||
namespace sophia {
|
||||
|
||||
Reference in New Issue
Block a user