We be kinda rendering
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <destrum/Graphics/GfxDevice.h>
|
||||
#include <destrum/Graphics/Renderer.h>
|
||||
|
||||
|
||||
class App {
|
||||
@@ -20,6 +21,8 @@ public:
|
||||
std::filesystem::path exeDir;
|
||||
};
|
||||
|
||||
App();
|
||||
|
||||
void init(const AppParams& params);
|
||||
void run();
|
||||
void cleanup();
|
||||
@@ -28,7 +31,15 @@ protected:
|
||||
SDL_Window* window{nullptr};
|
||||
AppParams m_params{};
|
||||
|
||||
CPUMesh testMesh{};
|
||||
MeshID testMeshID;
|
||||
|
||||
GfxDevice gfxDevice;
|
||||
GameRenderer renderer;
|
||||
|
||||
Camera camera{glm::vec3(0.f, 0.f, -5.f), glm::vec3(0, 1, 0)};
|
||||
|
||||
MeshCache meshCache;
|
||||
|
||||
bool isRunning{false};
|
||||
bool gamePaused{false};
|
||||
|
||||
158
destrum/include/destrum/Graphics/Camera.h
Normal file
158
destrum/include/destrum/Graphics/Camera.h
Normal file
@@ -0,0 +1,158 @@
|
||||
#ifndef VCAMERA_H
|
||||
#define VCAMERA_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
struct Frustum {
|
||||
glm::vec4 planes[6]; // left, right, bottom, top, near, far
|
||||
|
||||
void update(const glm::mat4& vpMatrix) {
|
||||
// Extract frustum planes from VP matrix (row-major, GLM style)
|
||||
glm::mat4 m = vpMatrix;
|
||||
|
||||
// Left
|
||||
planes[0] = glm::vec4(
|
||||
m[0][3] + m[0][0],
|
||||
m[1][3] + m[1][0],
|
||||
m[2][3] + m[2][0],
|
||||
m[3][3] + m[3][0]
|
||||
);
|
||||
// Right
|
||||
planes[1] = glm::vec4(
|
||||
m[0][3] - m[0][0],
|
||||
m[1][3] - m[1][0],
|
||||
m[2][3] - m[2][0],
|
||||
m[3][3] - m[3][0]
|
||||
);
|
||||
// Bottom
|
||||
planes[2] = glm::vec4(
|
||||
m[0][3] + m[0][1],
|
||||
m[1][3] + m[1][1],
|
||||
m[2][3] + m[2][1],
|
||||
m[3][3] + m[3][1]
|
||||
);
|
||||
// Top
|
||||
planes[3] = glm::vec4(
|
||||
m[0][3] - m[0][1],
|
||||
m[1][3] - m[1][1],
|
||||
m[2][3] - m[2][1],
|
||||
m[3][3] - m[3][1]
|
||||
);
|
||||
// Near
|
||||
planes[4] = glm::vec4(
|
||||
m[0][3] + m[0][2],
|
||||
m[1][3] + m[1][2],
|
||||
m[2][3] + m[2][2],
|
||||
m[3][3] + m[3][2]
|
||||
);
|
||||
// Far
|
||||
planes[5] = glm::vec4(
|
||||
m[0][3] - m[0][2],
|
||||
m[1][3] - m[1][2],
|
||||
m[2][3] - m[2][2],
|
||||
m[3][3] - m[3][2]
|
||||
);
|
||||
|
||||
// Normalize all planes
|
||||
for (auto& plane: planes) {
|
||||
float length = glm::length(glm::vec3(plane));
|
||||
plane /= length;
|
||||
}
|
||||
}
|
||||
|
||||
// Fast AABB-Frustum test
|
||||
// [[nodiscard]] bool isBoxVisible(const AABB& box) const {
|
||||
// for (const auto& plane: planes) {
|
||||
// glm::vec3 positive = box.min;
|
||||
// if (plane.x >= 0) positive.x = box.max.x;
|
||||
// if (plane.y >= 0) positive.y = box.max.y;
|
||||
// if (plane.z >= 0) positive.z = box.max.z;
|
||||
//
|
||||
// if (glm::dot(glm::vec3(plane), positive) + plane.w < 0) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
};
|
||||
|
||||
|
||||
explicit Camera(const glm::vec3& position, const glm::vec3& up);
|
||||
void Update(float deltaTime);
|
||||
|
||||
void CalculateViewMatrix();
|
||||
void CalculateProjectionMatrix();
|
||||
|
||||
[[nodiscard]] glm::mat4 GetViewMatrix() const { return m_viewMatrix; }
|
||||
[[nodiscard]] glm::mat4 GetProjectionMatrix() const { return m_projectionMatrix; }
|
||||
|
||||
[[nodiscard]] glm::mat4 GetViewProjectionMatrix() const { return m_projectionMatrix * m_viewMatrix; }
|
||||
|
||||
void setAspectRatio(float aspectRatio) {
|
||||
m_aspectRatio = aspectRatio;
|
||||
this->CalculateViewMatrix();
|
||||
this->CalculateProjectionMatrix();
|
||||
}
|
||||
|
||||
glm::vec3 m_position{2.f, 0, 0};
|
||||
|
||||
void Translate(const glm::vec3& translation) {
|
||||
m_position += translation;
|
||||
}
|
||||
|
||||
void SetTarget(const glm::vec3& target);
|
||||
void ClearTarget();
|
||||
void Target(const glm::vec3& target);
|
||||
[[nodiscard]] glm::vec3 GetTarget() const { return m_target; }
|
||||
[[nodiscard]] bool IsTargetting() const { return m_useTarget; }
|
||||
|
||||
[[nodiscard]] const Frustum& GetFrustum() const { return m_frustum; }
|
||||
|
||||
[[nodiscard]] glm::vec3 GetPosition() const { return m_position; }
|
||||
[[nodiscard]] glm::vec3 GetForward() const { return m_forward; }
|
||||
[[nodiscard]] glm::vec3 GetUp() const { return m_up; }
|
||||
[[nodiscard]] glm::vec3 GetRight() const { return m_right; }
|
||||
|
||||
void SetMovementSpeed(float speed) { m_movementSpeed = speed; }
|
||||
[[nodiscard]] float GetMovementSpeed() const { return m_movementSpeed; }
|
||||
|
||||
private:
|
||||
float fovAngle{90.f};
|
||||
float fov{tanf(glm::radians(fovAngle) / 2.f)};
|
||||
|
||||
glm::vec3 m_forward{1, 0, 0};
|
||||
glm::vec3 m_up{0, 1, 0};
|
||||
glm::vec3 m_right{0, 0, 1};
|
||||
|
||||
glm::vec3 m_target{0.0f, 0.0f, 0.0f};
|
||||
bool m_useTarget{false};
|
||||
|
||||
float totalPitch{0.0f};
|
||||
float totalYaw{0.0f};
|
||||
|
||||
glm::mat4 m_viewMatrix{};
|
||||
glm::mat4 m_invMatrix{};
|
||||
|
||||
glm::mat4 m_projectionMatrix{};
|
||||
|
||||
float m_aspectRatio{};
|
||||
float m_cameraSpeed{};
|
||||
float m_cameraSensitivity{};
|
||||
|
||||
float m_zNear{0.001f};
|
||||
float m_zFar{1000.0f};
|
||||
|
||||
float m_iso{100.f};
|
||||
float m_aperture{2.8f};
|
||||
float m_shutterSpeed{1.f / 60.f};
|
||||
|
||||
float m_scrollSpeed = 2.0f;
|
||||
|
||||
Frustum m_frustum{};
|
||||
|
||||
float m_movementSpeed{2.0f};
|
||||
};
|
||||
|
||||
#endif //VCAMERA_H
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef VIMAGE_H
|
||||
#define VIMAGE_H
|
||||
#ifndef GPUIMAGE_H
|
||||
#define GPUIMAGE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
@@ -7,29 +7,9 @@
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class VImage {
|
||||
public:
|
||||
glm::ivec2 getSize2D() const { return glm::ivec2{extent.width, extent.height}; }
|
||||
VkExtent2D getExtent2D() const { return VkExtent2D{extent.width, extent.height}; }
|
||||
#include <destrum/Graphics/ids.h>
|
||||
|
||||
std::uint32_t getBindlessId() const
|
||||
{
|
||||
assert(id != NULL_BINDLESS_ID && "Image wasn't added to bindless set");
|
||||
return id;
|
||||
}
|
||||
|
||||
void setBindlessId(const std::uint32_t id)
|
||||
{
|
||||
assert(id != NULL_BINDLESS_ID);
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
bool isInitialized() const { return id != NULL_BINDLESS_ID; }
|
||||
|
||||
VkImage getImage() const { return image; }
|
||||
VkImageView getImageView() const { return imageView; }
|
||||
VmaAllocation getAllocation() const { return allocation; }
|
||||
private:
|
||||
struct GPUImage {
|
||||
VkImage image;
|
||||
VkImageView imageView;
|
||||
VmaAllocation allocation;
|
||||
@@ -38,11 +18,29 @@ private:
|
||||
VkExtent3D extent;
|
||||
std::uint32_t mipLevels{1};
|
||||
std::uint32_t numLayers{1};
|
||||
bool isCubemap{false};
|
||||
std::string debugName{};
|
||||
|
||||
[[nodiscard]] glm::ivec2 getSize2D() const { return glm::ivec2{extent.width, extent.height}; }
|
||||
[[nodiscard]] VkExtent2D getExtent2D() const { return VkExtent2D{extent.width, extent.height}; }
|
||||
|
||||
[[nodiscard]] BindlessID getBindlessId() const
|
||||
{
|
||||
assert(id != NULL_BINDLESS_ID && "Image wasn't added to bindless set");
|
||||
return id;
|
||||
}
|
||||
|
||||
// should be called by ImageCache only
|
||||
void setBindlessId(const std::uint32_t id)
|
||||
{
|
||||
assert(id != NULL_BINDLESS_ID);
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isInitialized() const { return id != NULL_BINDLESS_ID; }
|
||||
|
||||
private:
|
||||
std::uint32_t id{NULL_BINDLESS_ID}; // bindless id - always equals to ImageId
|
||||
|
||||
static const auto NULL_BINDLESS_ID = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
};
|
||||
|
||||
#endif //VIMAGE_H
|
||||
#endif //GPUIMAGE_H
|
||||
@@ -6,20 +6,25 @@
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <destrum/Graphics/VImage.h>
|
||||
#include <destrum/Graphics/GPUImage.h>
|
||||
#include <destrum/Graphics/Swapchain.h>
|
||||
#include <destrum/Graphics/ImageCache.h>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <volk.h>
|
||||
#include <VkBootstrap.h>
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
|
||||
#include "ImmediateExecuter.h"
|
||||
|
||||
#include <destrum/Graphics/Swapchain.h>
|
||||
|
||||
using ImageId = std::uint32_t;
|
||||
static const auto NULL_IMAGE_ID = std::numeric_limits<std::uint32_t>::max();
|
||||
#include <destrum/Graphics/Resources/Buffer.h>
|
||||
#include <destrum/Graphics/ids.h>
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
namespace {
|
||||
using ImmediateExecuteFunction = std::function<void(VkCommandBuffer)>;
|
||||
@@ -40,14 +45,14 @@ public:
|
||||
void recreateSwapchain(int width, int height);
|
||||
|
||||
VkCommandBuffer beginFrame();
|
||||
bool needsSwapchainRecreate() const { return swapchain.isDirty(); }
|
||||
[[nodiscard]] bool needsSwapchainRecreate() const { return swapchain.isDirty(); }
|
||||
|
||||
|
||||
struct EndFrameProps {
|
||||
const VkClearColorValue clearColor{ {0.f, 0.f, 0.f, 1.f} };
|
||||
glm::ivec4 drawImageBlitRect{}; // where to blit draw image to
|
||||
};
|
||||
void endFrame(VkCommandBuffer cmd, const VImage& drawImage, const EndFrameProps& props);
|
||||
void endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const EndFrameProps& props);
|
||||
void cleanup();
|
||||
|
||||
void waitIdle();
|
||||
@@ -67,6 +72,29 @@ public:
|
||||
|
||||
VkExtent2D getSwapchainExtent() const { return swapchain.getExtent(); }
|
||||
|
||||
[[nodiscard]] GPUBuffer createBuffer(
|
||||
std::size_t allocSize,
|
||||
VkBufferUsageFlags usage,
|
||||
VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO) const;
|
||||
|
||||
[[nodiscard]] VkDeviceAddress getBufferAddress(const GPUBuffer& buffer) const;
|
||||
|
||||
void destroyBuffer(const GPUBuffer& buffer) const;
|
||||
|
||||
VmaAllocator getAllocator() const { return allocator; }
|
||||
|
||||
ImageID createImage(const vkutil::CreateImageInfo& createInfo, const std::string& debugName = "", void* pixelData = nullptr, ImageID imageId = NULL_IMAGE_ID);
|
||||
ImageID createDrawImage(VkFormat format, glm::ivec2 size, const std::string& debugName = "", ImageID imageId = NULL_IMAGE_ID);
|
||||
ImageID loadImageFromFile(const std::filesystem::path& path, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, bool mipMap = false);
|
||||
|
||||
ImageID addImageToCache(GPUImage image);
|
||||
|
||||
const GPUImage& getImage(ImageID id) const;
|
||||
void uploadImageData(const GPUImage& image, void* pixelData, std::uint32_t layer = 0) const;
|
||||
|
||||
GPUImage createImageRaw(const vkutil::CreateImageInfo& createInfo, std::optional<VmaAllocationCreateInfo> customAllocationCreateInfo = std::nullopt) const;
|
||||
GPUImage loadImageFromFileRaw(const std::filesystem::path& path, VkFormat format, VkImageUsageFlags usage, bool mipMap) const;
|
||||
void destroyImage(const GPUImage& image) const;
|
||||
|
||||
private:
|
||||
vkb::Instance instance;
|
||||
@@ -86,8 +114,11 @@ private:
|
||||
|
||||
VulkanImmediateExecutor executor;
|
||||
|
||||
ImageId whiteImageId{NULL_IMAGE_ID};
|
||||
ImageId errorImageId{NULL_IMAGE_ID};
|
||||
ImageID whiteImageId{NULL_IMAGE_ID};
|
||||
ImageID errorImageId{NULL_IMAGE_ID};
|
||||
|
||||
ImageCache imageCache;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
56
destrum/include/destrum/Graphics/ImageCache.h
Normal file
56
destrum/include/destrum/Graphics/ImageCache.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef IMAGECACHE_H
|
||||
#define IMAGECACHE_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <destrum/Graphics/ids.h>
|
||||
#include <destrum/Graphics/GPUImage.h>
|
||||
|
||||
// #include <destrum/Graphics/Vulkan/BindlessSetManager.h>
|
||||
|
||||
class GfxDevice;
|
||||
|
||||
class ImageCache {
|
||||
friend class ResourcesInspector;
|
||||
|
||||
public:
|
||||
ImageCache(GfxDevice& gfxDevice);
|
||||
|
||||
ImageID loadImageFromFile(
|
||||
const std::filesystem::path& path,
|
||||
VkFormat format,
|
||||
VkImageUsageFlags usage,
|
||||
bool mipMap);
|
||||
|
||||
ImageID addImage(GPUImage image);
|
||||
ImageID addImage(ImageID id, GPUImage image);
|
||||
const GPUImage& getImage(ImageID id) const;
|
||||
|
||||
ImageID getFreeImageId() const;
|
||||
|
||||
void destroyImages();
|
||||
|
||||
// BindlessSetManager bindlessSetManager;
|
||||
|
||||
void setErrorImageId(ImageID id) { errorImageId = id; }
|
||||
|
||||
private:
|
||||
std::vector<GPUImage> images;
|
||||
GfxDevice& gfxDevice;
|
||||
|
||||
struct LoadedImageInfo {
|
||||
std::filesystem::path path;
|
||||
VkFormat format;
|
||||
VkImageUsageFlags usage;
|
||||
bool mipMap;
|
||||
};
|
||||
std::unordered_map<ImageID, LoadedImageInfo> loadedImagesInfo;
|
||||
ImageID errorImageId{NULL_IMAGE_ID};
|
||||
};
|
||||
|
||||
|
||||
#endif //IMAGECACHE_H
|
||||
30
destrum/include/destrum/Graphics/Material.h
Normal file
30
destrum/include/destrum/Graphics/Material.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef MATERIAL_H
|
||||
#define MATERIAL_H
|
||||
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct MaterialData {
|
||||
glm::vec3 baseColor;
|
||||
glm::vec4 metalRoughnessEmissive;
|
||||
std::uint32_t diffuseTex;
|
||||
std::uint32_t normalTex;
|
||||
std::uint32_t metallicRoughnessTex;
|
||||
std::uint32_t emissiveTex;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
glm::vec3 baseColor{1.f, 1.f, 1.f};
|
||||
float metallicFactor{0.f};
|
||||
float roughnessFactor{0.7f};
|
||||
float emissiveFactor{0.f};
|
||||
|
||||
ImageID diffuseTexture{NULL_IMAGE_ID};
|
||||
// ImageId normalMapTexture{NULL_IMAGE_ID};
|
||||
// ImageId metallicRoughnessTexture{NULL_IMAGE_ID};
|
||||
// ImageId emissiveTexture{NULL_IMAGE_ID};
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
||||
#endif //MATERIAL_H
|
||||
42
destrum/include/destrum/Graphics/MaterialCache.h
Normal file
42
destrum/include/destrum/Graphics/MaterialCache.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef MATERIALCACHE_H
|
||||
#define MATERIALCACHE_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <destrum/Graphics/ids.h>
|
||||
#include <destrum/Graphics/Material.h>
|
||||
|
||||
#include <destrum/Graphics/Resources/Buffer.h>
|
||||
|
||||
class GfxDevice;
|
||||
|
||||
class MaterialCache {
|
||||
friend class ResourcesInspector;
|
||||
|
||||
public:
|
||||
void init(GfxDevice& gfxDevice);
|
||||
void cleanup(GfxDevice& gfxDevice);
|
||||
|
||||
MaterialId addMaterial(GfxDevice& gfxDevice, Material material);
|
||||
const Material& getMaterial(MaterialId id) const;
|
||||
|
||||
MaterialId getFreeMaterialId() const;
|
||||
MaterialId getPlaceholderMaterialId() const;
|
||||
|
||||
const GPUBuffer& getMaterialDataBuffer() const { return materialDataBuffer; }
|
||||
VkDeviceAddress getMaterialDataBufferAddress() const { return materialDataBuffer.address; }
|
||||
|
||||
private:
|
||||
std::vector<Material> materials;
|
||||
|
||||
static const auto MAX_MATERIALS = 1000;
|
||||
GPUBuffer materialDataBuffer;
|
||||
|
||||
// material which is used for meshes without materials
|
||||
MaterialId placeholderMaterialId{NULL_MATERIAL_ID};
|
||||
|
||||
ImageID defaultNormalMapTextureID{NULL_IMAGE_ID};
|
||||
};
|
||||
|
||||
|
||||
#endif //MATERIALCACHE_H
|
||||
@@ -1,4 +1,23 @@
|
||||
#ifndef MESHCACHE_H
|
||||
#define MESHCACHE_H
|
||||
|
||||
#include <destrum/Graphics/Resources/Mesh.h>
|
||||
|
||||
#include "ids.h"
|
||||
|
||||
class GfxDevice;
|
||||
|
||||
class MeshCache {
|
||||
public:
|
||||
void cleanup(const GfxDevice& gfxDevice);
|
||||
|
||||
MeshID addMesh(GfxDevice& gfxDevice, const CPUMesh& cpuMesh);
|
||||
const GPUMesh& getMesh(MeshID id) const;
|
||||
|
||||
private:
|
||||
void uploadMesh(GfxDevice& gfxDevice, const CPUMesh& cpuMesh, GPUMesh& gpuMesh) const;
|
||||
|
||||
std::vector<GPUMesh> meshes;
|
||||
};
|
||||
|
||||
#endif //MESHCACHE_H
|
||||
|
||||
27
destrum/include/destrum/Graphics/MeshDrawCommand.h
Normal file
27
destrum/include/destrum/Graphics/MeshDrawCommand.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef MESHDRAWCOMMAND_H
|
||||
#define MESHDRAWCOMMAND_H
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include <destrum/Graphics/ids.h>
|
||||
|
||||
|
||||
struct MeshDrawCommand {
|
||||
MeshID meshId;
|
||||
glm::mat4 transformMatrix;
|
||||
|
||||
// for frustum culling
|
||||
// math::Sphere worldBoundingSphere;
|
||||
|
||||
// If set - mesh will be drawn with overrideMaterialId
|
||||
// instead of whatever material the mesh has
|
||||
MaterialId materialId{NULL_MATERIAL_ID};
|
||||
|
||||
bool castShadow{true};
|
||||
|
||||
// skinned meshes only
|
||||
// const SkinnedMesh* skinnedMesh{nullptr};
|
||||
// std::uint32_t jointMatricesStartIndex;
|
||||
};
|
||||
|
||||
#endif //MESHDRAWCOMMAND_H
|
||||
@@ -5,13 +5,27 @@
|
||||
#include <memory>
|
||||
#include <destrum/Graphics/Pipeline.h>
|
||||
|
||||
#include <destrum/Graphics/MeshCache.h>
|
||||
#include <destrum/Graphics/MaterialCache.h>
|
||||
#include <destrum/Graphics/Camera.h>
|
||||
#include <destrum/Graphics/Resources/Buffer.h>
|
||||
#include <destrum/Graphics/MeshDrawCommand.h>
|
||||
|
||||
class MeshPipeline {
|
||||
public:
|
||||
MeshPipeline();
|
||||
~MeshPipeline();
|
||||
|
||||
void init(GfxDevice& gfxDevice, VkFormat drawImageFormat, VkFormat depthImageFormat);
|
||||
void draw();
|
||||
void draw(VkCommandBuffer cmd,
|
||||
VkExtent2D renderExtent,
|
||||
const GfxDevice& gfxDevice,
|
||||
const MeshCache& meshCache,
|
||||
const MaterialCache& materialCache,
|
||||
const Camera& camera,
|
||||
const GPUBuffer& sceneDataBuffer,
|
||||
const std::vector<MeshDrawCommand>& drawCommands,
|
||||
const std::vector<std::size_t>& sortedDrawCommands);
|
||||
|
||||
|
||||
private:
|
||||
@@ -19,6 +33,14 @@ private:
|
||||
|
||||
std::unique_ptr<Pipeline> m_pipeline;
|
||||
|
||||
struct PushConstants {
|
||||
glm::mat4 transform;
|
||||
VkDeviceAddress sceneDataBuffer;
|
||||
VkDeviceAddress vertexBuffer;
|
||||
std::uint32_t materialId;
|
||||
std::uint32_t padding;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //MESHPIPELINE_H
|
||||
|
||||
@@ -1,10 +1,82 @@
|
||||
#ifndef RENDERER_H
|
||||
#define RENDERER_H
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
#include <destrum/Graphics/Camera.h>
|
||||
#include <destrum/Graphics/Pipelines/MeshPipeline.h>
|
||||
#include <destrum/Graphics/MeshCache.h>
|
||||
#include <destrum/Graphics/ids.h>
|
||||
#include <destrum/Graphics/MeshDrawCommand.h>
|
||||
#include <destrum/Graphics/Resources/NBuffer.h>
|
||||
#include <destrum/Graphics/MaterialCache.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class GameRenderer {
|
||||
public:
|
||||
struct SceneData {
|
||||
const Camera& camera;
|
||||
glm::vec3 ambientColor;
|
||||
float ambientIntensity;
|
||||
glm::vec3 fogColor;
|
||||
float fogDensity;
|
||||
};
|
||||
|
||||
explicit GameRenderer(MeshCache& meshCache);
|
||||
|
||||
void init(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize);
|
||||
void beginDrawing(GfxDevice& gfxDevice);
|
||||
void endDrawing();
|
||||
|
||||
void draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera& camera, const SceneData& sceneData);
|
||||
void cleanup();
|
||||
|
||||
void drawMesh(MeshID id, const glm::mat4& transform, MaterialId materialId);
|
||||
|
||||
|
||||
private:
|
||||
void createDrawImage(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize, bool firstCreate);
|
||||
|
||||
MeshCache& meshCache;
|
||||
// MaterialCache& materialCache;
|
||||
|
||||
std::vector<MeshDrawCommand> meshDrawCommands;
|
||||
std::vector<std::size_t> sortedMeshDrawCommands;
|
||||
|
||||
VkFormat drawImageFormat{VK_FORMAT_R16G16B16A16_SFLOAT};
|
||||
VkFormat depthImageFormat{VK_FORMAT_D32_SFLOAT};
|
||||
|
||||
ImageID drawImageId{NULL_IMAGE_ID};
|
||||
ImageID depthImageId{NULL_IMAGE_ID};
|
||||
|
||||
VkSampleCountFlagBits samples{VK_SAMPLE_COUNT_1_BIT};
|
||||
|
||||
|
||||
struct GPUSceneData {
|
||||
// camera
|
||||
glm::mat4 view;
|
||||
glm::mat4 proj;
|
||||
glm::mat4 viewProj;
|
||||
glm::vec4 cameraPos;
|
||||
|
||||
// ambient
|
||||
glm::vec3 ambientColor;
|
||||
float ambientIntensity;
|
||||
|
||||
// fog
|
||||
glm::vec3 fogColor;
|
||||
float fogDensity;
|
||||
|
||||
VkDeviceAddress materialsBuffer;
|
||||
};
|
||||
|
||||
NBuffer sceneDataBuffer;
|
||||
|
||||
MaterialCache materialCache;
|
||||
|
||||
|
||||
std::unique_ptr<MeshPipeline> meshPipeline;
|
||||
};
|
||||
|
||||
#endif //RENDERER_H
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include <destrum/Graphics/Resources/Buffer.h>
|
||||
|
||||
struct CPUMesh {
|
||||
std::vector<std::uint32_t> indices;
|
||||
|
||||
@@ -38,15 +40,66 @@ struct GPUMesh {
|
||||
// AABB
|
||||
glm::vec3 minPos;
|
||||
glm::vec3 maxPos;
|
||||
math::Sphere boundingSphere;
|
||||
|
||||
bool hasSkeleton{false};
|
||||
// skinned meshes only
|
||||
GPUBuffer skinningDataBuffer;
|
||||
// math::Sphere boundingSphere;
|
||||
};
|
||||
|
||||
struct SkinnedMesh {
|
||||
GPUBuffer skinnedVertexBuffer;
|
||||
static std::vector<CPUMesh::Vertex> vertices = {
|
||||
// =======================
|
||||
// +Z (Front)
|
||||
// =======================
|
||||
{{-0.5f, -0.5f, 0.5f}, 0.0f, {0, 0, 1}, 0.0f, {1, 0, 0, 1}},
|
||||
{{ 0.5f, -0.5f, 0.5f}, 1.0f, {0, 0, 1}, 0.0f, {1, 0, 0, 1}},
|
||||
{{ 0.5f, 0.5f, 0.5f}, 1.0f, {0, 0, 1}, 1.0f, {1, 0, 0, 1}},
|
||||
{{-0.5f, 0.5f, 0.5f}, 0.0f, {0, 0, 1}, 1.0f, {1, 0, 0, 1}},
|
||||
|
||||
// =======================
|
||||
// -Z (Back)
|
||||
// =======================
|
||||
{{ 0.5f, -0.5f, -0.5f}, 0.0f, {0, 0, -1}, 0.0f, {-1, 0, 0, 1}},
|
||||
{{-0.5f, -0.5f, -0.5f}, 1.0f, {0, 0, -1}, 0.0f, {-1, 0, 0, 1}},
|
||||
{{-0.5f, 0.5f, -0.5f}, 1.0f, {0, 0, -1}, 1.0f, {-1, 0, 0, 1}},
|
||||
{{ 0.5f, 0.5f, -0.5f}, 0.0f, {0, 0, -1}, 1.0f, {-1, 0, 0, 1}},
|
||||
|
||||
// =======================
|
||||
// +X (Right)
|
||||
// =======================
|
||||
{{ 0.5f, -0.5f, 0.5f}, 0.0f, {1, 0, 0}, 0.0f, {0, 0, -1, 1}},
|
||||
{{ 0.5f, -0.5f, -0.5f}, 1.0f, {1, 0, 0}, 0.0f, {0, 0, -1, 1}},
|
||||
{{ 0.5f, 0.5f, -0.5f}, 1.0f, {1, 0, 0}, 1.0f, {0, 0, -1, 1}},
|
||||
{{ 0.5f, 0.5f, 0.5f}, 0.0f, {1, 0, 0}, 1.0f, {0, 0, -1, 1}},
|
||||
|
||||
// =======================
|
||||
// -X (Left)
|
||||
// =======================
|
||||
{{-0.5f, -0.5f, -0.5f}, 0.0f, {-1, 0, 0}, 0.0f, {0, 0, 1, 1}},
|
||||
{{-0.5f, -0.5f, 0.5f}, 1.0f, {-1, 0, 0}, 0.0f, {0, 0, 1, 1}},
|
||||
{{-0.5f, 0.5f, 0.5f}, 1.0f, {-1, 0, 0}, 1.0f, {0, 0, 1, 1}},
|
||||
{{-0.5f, 0.5f, -0.5f}, 0.0f, {-1, 0, 0}, 1.0f, {0, 0, 1, 1}},
|
||||
|
||||
// =======================
|
||||
// +Y (Top)
|
||||
// =======================
|
||||
{{-0.5f, 0.5f, 0.5f}, 0.0f, {0, 1, 0}, 0.0f, {1, 0, 0, 1}},
|
||||
{{ 0.5f, 0.5f, 0.5f}, 1.0f, {0, 1, 0}, 0.0f, {1, 0, 0, 1}},
|
||||
{{ 0.5f, 0.5f, -0.5f}, 1.0f, {0, 1, 0}, 1.0f, {1, 0, 0, 1}},
|
||||
{{-0.5f, 0.5f, -0.5f}, 0.0f, {0, 1, 0}, 1.0f, {1, 0, 0, 1}},
|
||||
|
||||
// =======================
|
||||
// -Y (Bottom)
|
||||
// =======================
|
||||
{{-0.5f, -0.5f, -0.5f}, 0.0f, {0, -1, 0}, 0.0f, {1, 0, 0, 1}},
|
||||
{{ 0.5f, -0.5f, -0.5f}, 1.0f, {0, -1, 0}, 0.0f, {1, 0, 0, 1}},
|
||||
{{ 0.5f, -0.5f, 0.5f}, 1.0f, {0, -1, 0}, 1.0f, {1, 0, 0, 1}},
|
||||
{{-0.5f, -0.5f, 0.5f}, 0.0f, {0, -1, 0}, 1.0f, {1, 0, 0, 1}},
|
||||
};
|
||||
|
||||
static std::vector<uint32_t> indices = {
|
||||
0, 1, 2, 2, 3, 0, // Front
|
||||
4, 5, 6, 6, 7, 4, // Back
|
||||
8, 9,10, 10,11, 8, // Right
|
||||
12,13,14, 14,15,12, // Left
|
||||
16,17,18, 18,19,16, // Top
|
||||
20,21,22, 22,23,20 // Bottom
|
||||
};
|
||||
|
||||
|
||||
|
||||
39
destrum/include/destrum/Graphics/Resources/NBuffer.h
Normal file
39
destrum/include/destrum/Graphics/Resources/NBuffer.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef NBUFFER_H
|
||||
#define NBUFFER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <destrum/Graphics/Resources/Buffer.h>
|
||||
|
||||
class GfxDevice;
|
||||
|
||||
class NBuffer {
|
||||
public:
|
||||
void init(
|
||||
GfxDevice& gfxDevice,
|
||||
VkBufferUsageFlags usage,
|
||||
std::size_t dataSize,
|
||||
const std::string& debugName = "");
|
||||
|
||||
void cleanup(GfxDevice& gfxDevice);
|
||||
|
||||
void uploadNewData(
|
||||
VkCommandBuffer cmd,
|
||||
std::size_t frameIndex,
|
||||
void* newData,
|
||||
std::size_t dataSize,
|
||||
std::size_t offset = 0,
|
||||
bool sync = true) const;
|
||||
|
||||
const GPUBuffer& getBuffer() const { return gpuBuffer; }
|
||||
|
||||
private:
|
||||
std::size_t framesInFlight{0};
|
||||
std::size_t gpuBufferSize{0};
|
||||
std::vector<GPUBuffer> stagingBuffers;
|
||||
GPUBuffer gpuBuffer;
|
||||
bool initialized{false};
|
||||
};
|
||||
|
||||
#endif //NBUFFER_H
|
||||
@@ -1,8 +1,11 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <filesystem>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "glm/vec4.hpp"
|
||||
|
||||
|
||||
#define VK_CHECK(call) \
|
||||
do { \
|
||||
@@ -11,6 +14,18 @@
|
||||
} while (0)
|
||||
|
||||
namespace vkutil {
|
||||
struct CreateImageInfo {
|
||||
VkFormat format;
|
||||
VkImageUsageFlags usage;
|
||||
VkImageCreateFlags flags;
|
||||
VkExtent3D extent{};
|
||||
std::uint32_t numLayers{1};
|
||||
VkSampleCountFlagBits samples{VK_SAMPLE_COUNT_1_BIT};
|
||||
VkImageTiling tiling{VK_IMAGE_TILING_OPTIMAL};
|
||||
bool mipMap{false};
|
||||
bool isCubemap{false};
|
||||
};
|
||||
|
||||
void transitionImage(
|
||||
VkCommandBuffer cmd,
|
||||
VkImage image,
|
||||
@@ -35,5 +50,32 @@ namespace vkutil {
|
||||
int destW,
|
||||
int destH,
|
||||
VkFilter filter);
|
||||
|
||||
void addDebugLabel(VkDevice device, VkImage image, const char* label);
|
||||
void addDebugLabel(VkDevice device, VkImageView imageView, const char* label);
|
||||
void addDebugLabel(VkDevice device, VkShaderModule shaderModule, const char* label);
|
||||
void addDebugLabel(VkDevice device, VkPipeline pipeline, const char* label);
|
||||
void addDebugLabel(VkDevice device, VkPipelineLayout layout, const char* label);
|
||||
void addDebugLabel(VkDevice device, VkBuffer buffer, const char* label);
|
||||
void addDebugLabel(VkDevice device, VkSampler sampler, const char* label);
|
||||
|
||||
struct RenderingInfoParams {
|
||||
VkExtent2D renderExtent;
|
||||
VkImageView colorImageView{VK_NULL_HANDLE};
|
||||
std::optional<glm::vec4> colorImageClearValue;
|
||||
VkImageView depthImageView{VK_NULL_HANDLE};
|
||||
std::optional<float> depthImageClearValue;
|
||||
};
|
||||
|
||||
struct RenderInfo {
|
||||
VkRenderingAttachmentInfo colorAttachment;
|
||||
VkRenderingAttachmentInfo depthAttachment;
|
||||
VkRenderingInfo renderingInfo;
|
||||
};
|
||||
|
||||
RenderInfo createRenderingInfo(const RenderingInfoParams& params);
|
||||
|
||||
VkShaderModule loadShaderModule(const std::filesystem::path& path, VkDevice device);
|
||||
|
||||
}
|
||||
#endif //UTIL_H
|
||||
|
||||
19
destrum/include/destrum/Graphics/ids.h
Normal file
19
destrum/include/destrum/Graphics/ids.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef IDS_H
|
||||
#define IDS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
using MeshID = std::size_t;
|
||||
constexpr MeshID NULL_MESH_ID = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
using ImageID = std::uint16_t;
|
||||
constexpr ImageID NULL_IMAGE_ID = std::numeric_limits<std::uint16_t>::max();
|
||||
|
||||
using MaterialId = std::uint32_t;
|
||||
constexpr MaterialId NULL_MATERIAL_ID = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
using BindlessID = std::uint32_t;
|
||||
constexpr BindlessID NULL_BINDLESS_ID = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
#endif //IDS_H
|
||||
36
destrum/include/destrum/Graphics/imageLoader.h
Normal file
36
destrum/include/destrum/Graphics/imageLoader.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef IMAGELOADER_H
|
||||
#define IMAGELOADER_H
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
struct ImageData {
|
||||
ImageData() = default;
|
||||
~ImageData();
|
||||
|
||||
// move only
|
||||
ImageData(ImageData&& o) = default;
|
||||
ImageData& operator=(ImageData&& o) = default;
|
||||
|
||||
// no copies
|
||||
ImageData(const ImageData& o) = delete;
|
||||
ImageData& operator=(const ImageData& o) = delete;
|
||||
|
||||
// data
|
||||
unsigned char* pixels{nullptr};
|
||||
int width{0};
|
||||
int height{0};
|
||||
int channels{0};
|
||||
|
||||
// HDR only
|
||||
float* hdrPixels{nullptr};
|
||||
bool hdr{false};
|
||||
int comp{0};
|
||||
|
||||
bool shouldSTBFree{false};
|
||||
};
|
||||
|
||||
namespace util {
|
||||
ImageData loadImage(const std::filesystem::path& p);
|
||||
}
|
||||
|
||||
#endif //IMAGELOADER_H
|
||||
Reference in New Issue
Block a user