We got exr loading
This commit is contained in:
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -32,4 +32,6 @@
|
|||||||
[submodule "destrum/third_party/tinygltf"]
|
[submodule "destrum/third_party/tinygltf"]
|
||||||
path = destrum/third_party/tinygltf
|
path = destrum/third_party/tinygltf
|
||||||
url = https://github.com/syoyo/tinygltf.git
|
url = https://github.com/syoyo/tinygltf.git
|
||||||
|
[submodule "destrum/third_party/tinyexr"]
|
||||||
|
path = destrum/third_party/tinyexr
|
||||||
|
url = https://github.com/syoyo/tinyexr.git
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ target_link_libraries(destrum
|
|||||||
|
|
||||||
PRIVATE
|
PRIVATE
|
||||||
freetype::freetype
|
freetype::freetype
|
||||||
|
tinyexr
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(destrum
|
target_compile_definitions(destrum
|
||||||
|
|||||||
@@ -15,21 +15,15 @@ layout(push_constant) uniform SkyboxPC {
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Fullscreen-triangle trick gives uv in [0..2]. Convert to [0..1].
|
vec2 ndcXY = uv * 2.0 - 1.0;
|
||||||
vec2 uv01 = uv * 0.5;
|
|
||||||
|
|
||||||
// Build an NDC point on the far plane.
|
vec4 ndc = vec4(ndcXY, 1.0, 1.0);
|
||||||
// Vulkan NDC is x,y in [-1..1], z in [0..1]. Using z=1 means "far".
|
|
||||||
vec4 ndc = vec4(uv01 * 2.0 - 1.0, 1.0, 1.0);
|
|
||||||
|
|
||||||
// Unproject to world space
|
|
||||||
vec4 world = pcs.invViewProj * ndc;
|
vec4 world = pcs.invViewProj * ndc;
|
||||||
vec3 worldPos = world.xyz / world.w;
|
vec3 worldPos = world.xyz / world.w;
|
||||||
|
|
||||||
// Direction from camera through this pixel
|
|
||||||
vec3 dir = normalize(worldPos - pcs.cameraPos.xyz);
|
vec3 dir = normalize(worldPos - pcs.cameraPos.xyz);
|
||||||
|
dir.y *= -1.0;
|
||||||
|
|
||||||
// Sample cubemap directly
|
|
||||||
outColor = sampleTextureCubeLinear(pcs.skyboxTextureId, dir);
|
outColor = sampleTextureCubeLinear(pcs.skyboxTextureId, dir);
|
||||||
// outColor = sampleTextureCubeNearest(pcs.skyboxTextureId, dir);
|
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
destrum/assets_src/textures/mars.jpg
Normal file
BIN
destrum/assets_src/textures/mars.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 354 KiB |
@@ -45,6 +45,9 @@ private:
|
|||||||
glm::vec3 m_BaseScale{1.0f};
|
glm::vec3 m_BaseScale{1.0f};
|
||||||
float m_GrowSpeed = 1.0f; // rad/sec
|
float m_GrowSpeed = 1.0f; // rad/sec
|
||||||
|
|
||||||
|
float m_GrowMin = 0.05f;
|
||||||
|
float m_GrowMax = 0.3f;
|
||||||
|
|
||||||
// self spin
|
// self spin
|
||||||
glm::vec3 m_SpinAxis{0,1,0};
|
glm::vec3 m_SpinAxis{0,1,0};
|
||||||
float m_SpinSpeed = 2.0f; // rad/sec
|
float m_SpinSpeed = 2.0f; // rad/sec
|
||||||
|
|||||||
@@ -50,9 +50,10 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
struct EndFrameProps {
|
struct EndFrameProps {
|
||||||
const VkClearColorValue clearColor{ {0.f, 0.f, 0.f, 1.f} };
|
const VkClearColorValue clearColor{{0.f, 0.f, 0.f, 1.f}};
|
||||||
glm::ivec4 drawImageBlitRect{}; // where to blit draw image to
|
glm::ivec4 drawImageBlitRect{}; // where to blit draw image to
|
||||||
};
|
};
|
||||||
|
|
||||||
void endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const EndFrameProps& props);
|
void endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const EndFrameProps& props);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
@@ -67,8 +68,7 @@ public:
|
|||||||
|
|
||||||
vkb::Device getDevice() const { return device; }
|
vkb::Device getDevice() const { return device; }
|
||||||
|
|
||||||
std::uint32_t getCurrentFrameIndex() const
|
std::uint32_t getCurrentFrameIndex() const {
|
||||||
{
|
|
||||||
return frameNumber % FRAMES_IN_FLIGHT;
|
return frameNumber % FRAMES_IN_FLIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,18 +91,20 @@ public:
|
|||||||
|
|
||||||
ImageID createImage(const vkutil::CreateImageInfo& createInfo, const std::string& debugName = "", void* pixelData = nullptr, ImageID imageId = NULL_IMAGE_ID);
|
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 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 loadImageFromFile(const std::filesystem::path& path, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, bool mipMap = false, TextureIntent intent = TextureIntent::ColorSrgb);
|
||||||
|
|
||||||
|
|
||||||
ImageID addImageToCache(GPUImage image);
|
ImageID addImageToCache(GPUImage image);
|
||||||
|
|
||||||
const GPUImage& getImage(ImageID id) const;
|
[[nodiscard]] const GPUImage& getImage(ImageID id) const;
|
||||||
void uploadImageData(const GPUImage& image, void* pixelData, std::uint32_t layer = 0) const;
|
// void uploadImageData(const GPUImage& image, void* pixelData, std::uint32_t layer = 0) const;
|
||||||
|
void uploadImageDataSized(const GPUImage& image, const void* pixelData, std::size_t byteSize, std::uint32_t layer) const;
|
||||||
|
|
||||||
GPUImage createImageRaw(const vkutil::CreateImageInfo& createInfo, std::optional<VmaAllocationCreateInfo> customAllocationCreateInfo = std::nullopt) const;
|
[[nodiscard]] 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;
|
GPUImage loadImageFromFileRaw(const std::filesystem::path& path, VkImageUsageFlags usage, bool mipMap, TextureIntent intent) const;
|
||||||
void destroyImage(const GPUImage& image) const;
|
void destroyImage(const GPUImage& image) const;
|
||||||
|
|
||||||
ImageID getWhiteTextureID() { return whiteImageId; }
|
[[nodiscard]] ImageID getWhiteTextureID() const { return whiteImageId; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vkb::Instance instance;
|
vkb::Instance instance;
|
||||||
@@ -129,17 +131,16 @@ private:
|
|||||||
|
|
||||||
static uint32_t BytesPerTexel(VkFormat fmt) {
|
static uint32_t BytesPerTexel(VkFormat fmt) {
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case VK_FORMAT_R8_UNORM: return 1;
|
case VK_FORMAT_R8_UNORM: return 1;
|
||||||
case VK_FORMAT_R8G8B8A8_UNORM: return 4;
|
case VK_FORMAT_R8G8B8A8_UNORM: return 4;
|
||||||
case VK_FORMAT_B8G8R8A8_SRGB: return 4;
|
case VK_FORMAT_B8G8R8A8_SRGB: return 4;
|
||||||
case VK_FORMAT_R16G16B16A16_SFLOAT: return 8;
|
case VK_FORMAT_R16G16B16A16_SFLOAT: return 8;
|
||||||
case VK_FORMAT_R32G32B32A32_SFLOAT: return 16;
|
case VK_FORMAT_R32G32B32A32_SFLOAT: return 16;
|
||||||
case VK_FORMAT_R8G8B8A8_SRGB: return 4;
|
case VK_FORMAT_R8G8B8A8_SRGB: return 4;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("BytesPerTexel: unsupported format");
|
throw std::runtime_error("BytesPerTexel: unsupported format");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,10 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <destrum/Graphics/ids.h>
|
|
||||||
#include <destrum/Graphics/GPUImage.h>
|
|
||||||
#include <destrum/Graphics/BindlessSetManager.h>
|
#include <destrum/Graphics/BindlessSetManager.h>
|
||||||
|
#include <destrum/Graphics/GPUImage.h>
|
||||||
// #include <destrum/Graphics/Vulkan/BindlessSetManager.h>
|
#include <destrum/Graphics/ids.h>
|
||||||
|
#include <destrum/Graphics/TextureIntent.h>
|
||||||
|
|
||||||
class GfxDevice;
|
class GfxDevice;
|
||||||
|
|
||||||
@@ -19,19 +18,18 @@ class ImageCache {
|
|||||||
friend class ResourcesInspector;
|
friend class ResourcesInspector;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ImageCache(GfxDevice& gfxDevice);
|
explicit ImageCache(GfxDevice& gfxDevice);
|
||||||
|
|
||||||
ImageID loadImageFromFile(
|
ImageID loadImageFromFile(
|
||||||
const std::filesystem::path& path,
|
const std::filesystem::path& path,
|
||||||
VkFormat format,
|
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
bool mipMap);
|
bool mipMap, TextureIntent intent = TextureIntent::ColorSrgb);
|
||||||
|
|
||||||
ImageID addImage(GPUImage image);
|
ImageID addImage(GPUImage image);
|
||||||
ImageID addImage(ImageID id, GPUImage image);
|
ImageID addImage(ImageID id, GPUImage image);
|
||||||
const GPUImage& getImage(ImageID id) const;
|
[[nodiscard]] const GPUImage& getImage(ImageID id) const;
|
||||||
|
|
||||||
ImageID getFreeImageId() const;
|
[[nodiscard]] ImageID getFreeImageId() const;
|
||||||
|
|
||||||
void destroyImages();
|
void destroyImages();
|
||||||
|
|
||||||
@@ -55,7 +53,7 @@ private:
|
|||||||
|
|
||||||
struct LoadedImageInfo {
|
struct LoadedImageInfo {
|
||||||
std::filesystem::path path;
|
std::filesystem::path path;
|
||||||
VkFormat format;
|
TextureIntent intent;
|
||||||
VkImageUsageFlags usage;
|
VkImageUsageFlags usage;
|
||||||
bool mipMap;
|
bool mipMap;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -46,12 +46,15 @@ public:
|
|||||||
|
|
||||||
void setSkyboxTexture(ImageID skyboxImageId);
|
void setSkyboxTexture(ImageID skyboxImageId);
|
||||||
|
|
||||||
|
void flushMaterialUpdates(GfxDevice& gfxDevice);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createDrawImage(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize, bool firstCreate);
|
void createDrawImage(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize, bool firstCreate);
|
||||||
|
|
||||||
MeshCache& meshCache;
|
MeshCache& meshCache;
|
||||||
MaterialCache& materialCache;
|
MaterialCache& materialCache;
|
||||||
|
std::vector<MaterialID> pendingMaterialUploads;
|
||||||
|
|
||||||
|
|
||||||
std::vector<MeshDrawCommand> meshDrawCommands;
|
std::vector<MeshDrawCommand> meshDrawCommands;
|
||||||
std::vector<std::size_t> sortedMeshDrawCommands;
|
std::vector<std::size_t> sortedMeshDrawCommands;
|
||||||
|
|||||||
11
destrum/include/destrum/Graphics/TextureIntent.h
Normal file
11
destrum/include/destrum/Graphics/TextureIntent.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef TEXTUREINTENT_H
|
||||||
|
#define TEXTUREINTENT_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
enum class TextureIntent : std::uint8_t {
|
||||||
|
ColorSrgb, // albedo/UI
|
||||||
|
DataLinear, // normal/roughness/metalness/etc
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //TEXTUREINTENT_H
|
||||||
@@ -51,6 +51,12 @@ namespace vkutil {
|
|||||||
int destH,
|
int destH,
|
||||||
VkFilter filter);
|
VkFilter filter);
|
||||||
|
|
||||||
|
void bufferHostWriteToShaderReadBarrier(
|
||||||
|
VkCommandBuffer cmd,
|
||||||
|
VkBuffer buffer,
|
||||||
|
VkDeviceSize offset = 0,
|
||||||
|
VkDeviceSize size = VK_WHOLE_SIZE);
|
||||||
|
|
||||||
void addDebugLabel(VkDevice device, VkImage image, const char* label);
|
void addDebugLabel(VkDevice device, VkImage image, const char* label);
|
||||||
void addDebugLabel(VkDevice device, VkImageView imageView, 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, VkShaderModule shaderModule, const char* label);
|
||||||
@@ -76,6 +82,5 @@ namespace vkutil {
|
|||||||
RenderInfo createRenderingInfo(const RenderingInfoParams& params);
|
RenderInfo createRenderingInfo(const RenderingInfoParams& params);
|
||||||
|
|
||||||
VkShaderModule loadShaderModule(const std::filesystem::path& path, VkDevice device);
|
VkShaderModule loadShaderModule(const std::filesystem::path& path, VkDevice device);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif //UTIL_H
|
#endif //UTIL_H
|
||||||
|
|||||||
@@ -1,36 +1,73 @@
|
|||||||
#ifndef IMAGELOADER_H
|
#ifndef IMAGELOADER_H
|
||||||
#define IMAGELOADER_H
|
#define IMAGELOADER_H
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
#include "destrum/Graphics/TextureIntent.h"
|
||||||
|
|
||||||
struct ImageData {
|
struct ImageData {
|
||||||
ImageData() = default;
|
ImageData() = default;
|
||||||
~ImageData();
|
~ImageData();
|
||||||
|
|
||||||
// move only
|
// move only (CUSTOM!)
|
||||||
ImageData(ImageData&& o) = default;
|
ImageData(ImageData&& o) noexcept { *this = std::move(o); }
|
||||||
ImageData& operator=(ImageData&& o) = default;
|
|
||||||
|
|
||||||
// no copies
|
|
||||||
ImageData(const ImageData& o) = delete;
|
|
||||||
ImageData& operator=(const ImageData& o) = delete;
|
|
||||||
|
|
||||||
// data
|
ImageData& operator=(ImageData&& o) noexcept {
|
||||||
|
if (this == &o) return *this;
|
||||||
|
|
||||||
|
// free current contents first
|
||||||
|
this->~ImageData();
|
||||||
|
|
||||||
|
// steal
|
||||||
|
pixels = o.pixels;
|
||||||
|
hdrPixels = o.hdrPixels;
|
||||||
|
hdr = o.hdr;
|
||||||
|
width = o.width;
|
||||||
|
height = o.height;
|
||||||
|
channels = o.channels;
|
||||||
|
comp = o.comp;
|
||||||
|
shouldSTBFree = o.shouldSTBFree;
|
||||||
|
shouldEXRFree = o.shouldEXRFree;
|
||||||
|
vkFormat = o.vkFormat;
|
||||||
|
byteSize = o.byteSize;
|
||||||
|
|
||||||
|
// neuter source so its destructor won't free our memory
|
||||||
|
o.pixels = nullptr;
|
||||||
|
o.hdrPixels = nullptr;
|
||||||
|
o.shouldSTBFree = false;
|
||||||
|
o.shouldEXRFree = false;
|
||||||
|
o.hdr = false;
|
||||||
|
o.width = o.height = o.channels = o.comp = 0;
|
||||||
|
o.vkFormat = VK_FORMAT_UNDEFINED;
|
||||||
|
o.byteSize = 0;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageData(const ImageData&) = delete;
|
||||||
|
ImageData& operator=(const ImageData&) = delete;
|
||||||
|
|
||||||
unsigned char* pixels{nullptr};
|
unsigned char* pixels{nullptr};
|
||||||
|
float* hdrPixels{nullptr};
|
||||||
|
bool hdr{false};
|
||||||
|
|
||||||
int width{0};
|
int width{0};
|
||||||
int height{0};
|
int height{0};
|
||||||
int channels{0};
|
int channels{0};
|
||||||
|
|
||||||
// HDR only
|
|
||||||
float* hdrPixels{nullptr};
|
|
||||||
bool hdr{false};
|
|
||||||
int comp{0};
|
int comp{0};
|
||||||
|
|
||||||
bool shouldSTBFree{false};
|
bool shouldSTBFree{false};
|
||||||
|
bool shouldEXRFree{false};
|
||||||
|
|
||||||
|
VkFormat vkFormat{VK_FORMAT_UNDEFINED};
|
||||||
|
std::size_t byteSize{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
ImageData loadImage(const std::filesystem::path& p);
|
ImageData loadImage(const std::filesystem::path& p, TextureIntent intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //IMAGELOADER_H
|
#endif // IMAGELOADER_H
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ void OrbitAndSpin::Randomize(uint32_t seed)
|
|||||||
std::uniform_real_distribution<float> spinSpeedDist(0.5f, 6.0f);
|
std::uniform_real_distribution<float> spinSpeedDist(0.5f, 6.0f);
|
||||||
std::uniform_real_distribution<float> phaseDist(0.0f, 6.28318530718f);
|
std::uniform_real_distribution<float> phaseDist(0.0f, 6.28318530718f);
|
||||||
|
|
||||||
|
// grow randomness
|
||||||
|
std::uniform_real_distribution<float> growMinDist(0.03f, 0.08f);
|
||||||
|
std::uniform_real_distribution<float> growMaxDist(0.2f, 0.4f);
|
||||||
|
std::uniform_real_distribution<float> growSpeedDist(0.5f, 2.5f);
|
||||||
|
|
||||||
m_OrbitAxis = RandomUnitVector(rng);
|
m_OrbitAxis = RandomUnitVector(rng);
|
||||||
m_SpinAxis = RandomUnitVector(rng);
|
m_SpinAxis = RandomUnitVector(rng);
|
||||||
|
|
||||||
@@ -35,6 +40,15 @@ void OrbitAndSpin::Randomize(uint32_t seed)
|
|||||||
m_SpinSpeed = spinSpeedDist(rng);
|
m_SpinSpeed = spinSpeedDist(rng);
|
||||||
m_OrbitPhase = phaseDist(rng);
|
m_OrbitPhase = phaseDist(rng);
|
||||||
|
|
||||||
|
m_GrowMin = growMinDist(rng);
|
||||||
|
m_GrowMax = growMaxDist(rng);
|
||||||
|
m_GrowSpeed = growSpeedDist(rng);
|
||||||
|
m_GrowPhase = phaseDist(rng); // random start offset
|
||||||
|
|
||||||
|
// safety: ensure min < max
|
||||||
|
if (m_GrowMin > m_GrowMax)
|
||||||
|
std::swap(m_GrowMin, m_GrowMax);
|
||||||
|
|
||||||
BuildOrbitBasis();
|
BuildOrbitBasis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,19 +84,27 @@ void OrbitAndSpin::Update()
|
|||||||
// grow (always positive)
|
// grow (always positive)
|
||||||
m_GrowPhase += m_GrowSpeed * dt;
|
m_GrowPhase += m_GrowSpeed * dt;
|
||||||
|
|
||||||
float t = 0.5f * (std::sin(m_GrowPhase) + 1.0f); // 0..1
|
m_GrowPhase += m_GrowSpeed * dt;
|
||||||
float s = 1.50 + t * 0.70f; // 0.05..0.15 (pick what you want)
|
|
||||||
|
|
||||||
GetTransform().SetLocalScale(glm::vec3(std::sin(m_GrowPhase)));
|
// 0..1
|
||||||
|
float t = 0.5f * (std::sin(m_GrowPhase) + 1.0f);
|
||||||
|
|
||||||
|
// random per-object range
|
||||||
|
float s = glm::mix(m_GrowMin, m_GrowMax, t);
|
||||||
|
|
||||||
|
// respect original scale
|
||||||
|
GetTransform().SetLocalScale(glm::vec3(s));
|
||||||
|
|
||||||
|
// GetTransform().SetLocalScale(glm::vec3(std::sin(m_GrowPhase)));
|
||||||
|
|
||||||
// material color
|
// material color
|
||||||
// auto& mat = GameState::GetInstance().Renderer().getMaterialMutable(m_MaterialID);
|
auto& mat = GameState::GetInstance().Renderer().getMaterialMutable(m_MaterialID);
|
||||||
// mat.baseColor = glm::vec3(
|
mat.baseColor = glm::vec3(
|
||||||
// 0.5f + 0.5f * std::sin(m_OrbitAngle * 2.0f),
|
0.5f + 0.5f * std::sin(m_OrbitAngle * 2.0f),
|
||||||
// 0.5f + 0.5f * std::sin(m_OrbitAngle * 3.0f + 2.0f),
|
0.5f + 0.5f * std::sin(m_OrbitAngle * 3.0f + 2.0f),
|
||||||
// 0.5f + 0.5f * std::sin(m_OrbitAngle * 4.0f + 4.0f)
|
0.5f + 0.5f * std::sin(m_OrbitAngle * 4.0f + 4.0f)
|
||||||
// );
|
);
|
||||||
// GameState::GetInstance().Renderer().updateMaterialGPU(m_MaterialID);
|
GameState::GetInstance().Renderer().updateMaterialGPU(m_MaterialID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrbitAndSpin::Start() {
|
void OrbitAndSpin::Start() {
|
||||||
|
|||||||
@@ -104,9 +104,8 @@ void GfxDevice::init(SDL_Window* window, const std::string& appName, bool vSync)
|
|||||||
VkPhysicalDeviceProperties props{};
|
VkPhysicalDeviceProperties props{};
|
||||||
vkGetPhysicalDeviceProperties(physicalDevice, &props);
|
vkGetPhysicalDeviceProperties(physicalDevice, &props);
|
||||||
|
|
||||||
imageCache.bindlessSetManager.init(device, props.limits.maxSamplerAnisotropy);
|
imageCache.bindlessSetManager.init(device, props.limits.maxSamplerAnisotropy); {
|
||||||
|
// create white texture
|
||||||
{ // create white texture
|
|
||||||
std::uint32_t pixel = 0xFFFFFFFF;
|
std::uint32_t pixel = 0xFFFFFFFF;
|
||||||
whiteImageId = createImage(
|
whiteImageId = createImage(
|
||||||
{
|
{
|
||||||
@@ -170,7 +169,7 @@ VulkanImmediateExecutor& GfxDevice::GetImmediateExecuter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GfxDevice::endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const EndFrameProps& props) {
|
void GfxDevice::endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const EndFrameProps& props) {
|
||||||
// get swapchain image
|
// get swapchain image
|
||||||
const auto [swapchainImage, swapchainImageIndex] = swapchain.acquireNextImage(getCurrentFrameIndex());
|
const auto [swapchainImage, swapchainImageIndex] = swapchain.acquireNextImage(getCurrentFrameIndex());
|
||||||
if (swapchainImage == VK_NULL_HANDLE) {
|
if (swapchainImage == VK_NULL_HANDLE) {
|
||||||
spdlog::info("Swapchain is freaky, skipping frame...");
|
spdlog::info("Swapchain is freaky, skipping frame...");
|
||||||
@@ -180,9 +179,7 @@ void GfxDevice::endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const E
|
|||||||
// Fences are reset here to prevent the deadlock in case swapchain becomes dirty
|
// Fences are reset here to prevent the deadlock in case swapchain becomes dirty
|
||||||
swapchain.resetFences(getCurrentFrameIndex());
|
swapchain.resetFences(getCurrentFrameIndex());
|
||||||
|
|
||||||
auto swapchainLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
auto swapchainLayout = VK_IMAGE_LAYOUT_UNDEFINED; {
|
||||||
|
|
||||||
{
|
|
||||||
const VkImageSubresourceRange clearRange = vkinit::imageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
const VkImageSubresourceRange clearRange = vkinit::imageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
vkutil::transitionImage(cmd, swapchainImage, swapchainLayout, VK_IMAGE_LAYOUT_GENERAL);
|
vkutil::transitionImage(cmd, swapchainImage, swapchainLayout, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
swapchainLayout = VK_IMAGE_LAYOUT_GENERAL;
|
swapchainLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
@@ -277,8 +274,7 @@ void GfxDevice::immediateSubmit(ImmediateExecuteFunction&& f) const {
|
|||||||
GPUBuffer GfxDevice::createBuffer(
|
GPUBuffer GfxDevice::createBuffer(
|
||||||
std::size_t allocSize,
|
std::size_t allocSize,
|
||||||
VkBufferUsageFlags usage,
|
VkBufferUsageFlags usage,
|
||||||
VmaMemoryUsage memoryUsage) const
|
VmaMemoryUsage memoryUsage) const {
|
||||||
{
|
|
||||||
const auto bufferInfo = VkBufferCreateInfo{
|
const auto bufferInfo = VkBufferCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
.size = allocSize,
|
.size = allocSize,
|
||||||
@@ -305,8 +301,7 @@ GPUBuffer GfxDevice::createBuffer(
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDeviceAddress GfxDevice::getBufferAddress(const GPUBuffer& buffer) const
|
VkDeviceAddress GfxDevice::getBufferAddress(const GPUBuffer& buffer) const {
|
||||||
{
|
|
||||||
const auto deviceAdressInfo = VkBufferDeviceAddressInfo{
|
const auto deviceAdressInfo = VkBufferDeviceAddressInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
|
||||||
.buffer = buffer.buffer,
|
.buffer = buffer.buffer,
|
||||||
@@ -314,10 +309,10 @@ VkDeviceAddress GfxDevice::getBufferAddress(const GPUBuffer& buffer) const
|
|||||||
return vkGetBufferDeviceAddress(device, &deviceAdressInfo);
|
return vkGetBufferDeviceAddress(device, &deviceAdressInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxDevice::destroyBuffer(const GPUBuffer& buffer) const
|
void GfxDevice::destroyBuffer(const GPUBuffer& buffer) const {
|
||||||
{
|
|
||||||
vmaDestroyBuffer(allocator, buffer.buffer, buffer.allocation);
|
vmaDestroyBuffer(allocator, buffer.buffer, buffer.allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// GPUImage GfxDevice::loadImageFromFileRaw(
|
// GPUImage GfxDevice::loadImageFromFileRaw(
|
||||||
// const std::filesystem::path& path,
|
// const std::filesystem::path& path,
|
||||||
@@ -356,15 +351,20 @@ ImageID GfxDevice::createImage(
|
|||||||
const vkutil::CreateImageInfo& createInfo,
|
const vkutil::CreateImageInfo& createInfo,
|
||||||
const std::string& debugName,
|
const std::string& debugName,
|
||||||
void* pixelData,
|
void* pixelData,
|
||||||
ImageID imageId)
|
ImageID imageId) {
|
||||||
{
|
|
||||||
auto image = createImageRaw(createInfo);
|
auto image = createImageRaw(createInfo);
|
||||||
if (!debugName.empty()) {
|
if (!debugName.empty()) {
|
||||||
vkutil::addDebugLabel(device, image.image, debugName.c_str());
|
vkutil::addDebugLabel(device, image.image, debugName.c_str());
|
||||||
image.debugName = debugName;
|
image.debugName = debugName;
|
||||||
}
|
}
|
||||||
if (pixelData) {
|
if (pixelData) {
|
||||||
uploadImageData(image, pixelData);
|
const std::size_t bytes =
|
||||||
|
std::size_t(image.extent.width) *
|
||||||
|
std::size_t(image.extent.height) *
|
||||||
|
std::size_t(image.extent.depth) *
|
||||||
|
BytesPerTexel(image.format);
|
||||||
|
|
||||||
|
uploadImageDataSized(image, pixelData, bytes, 0);
|
||||||
}
|
}
|
||||||
if (imageId != NULL_IMAGE_ID) {
|
if (imageId != NULL_IMAGE_ID) {
|
||||||
return imageCache.addImage(imageId, std::move(image));
|
return imageCache.addImage(imageId, std::move(image));
|
||||||
@@ -377,8 +377,7 @@ ImageID GfxDevice::createDrawImage(
|
|||||||
VkFormat format,
|
VkFormat format,
|
||||||
glm::ivec2 size,
|
glm::ivec2 size,
|
||||||
const std::string& debugName,
|
const std::string& debugName,
|
||||||
ImageID imageId)
|
ImageID imageId) {
|
||||||
{
|
|
||||||
assert(size.x > 0 && size.y > 0);
|
assert(size.x > 0 && size.y > 0);
|
||||||
const auto extent = VkExtent3D{
|
const auto extent = VkExtent3D{
|
||||||
.width = (std::uint32_t)size.x,
|
.width = (std::uint32_t)size.x,
|
||||||
@@ -400,29 +399,21 @@ ImageID GfxDevice::createDrawImage(
|
|||||||
return createImage(createImageInfo, debugName, nullptr, imageId);
|
return createImage(createImageInfo, debugName, nullptr, imageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageID GfxDevice::loadImageFromFile(
|
ImageID GfxDevice::loadImageFromFile(const std::filesystem::path& path, VkImageUsageFlags usage, bool mipMap, TextureIntent intent) {
|
||||||
const std::filesystem::path& path,
|
return imageCache.loadImageFromFile(path, usage, mipMap, intent);
|
||||||
VkFormat format,
|
|
||||||
VkImageUsageFlags usage,
|
|
||||||
bool mipMap)
|
|
||||||
{
|
|
||||||
return imageCache.loadImageFromFile(path, format, usage, mipMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const GPUImage& GfxDevice::getImage(ImageID id) const
|
const GPUImage& GfxDevice::getImage(ImageID id) const {
|
||||||
{
|
|
||||||
return imageCache.getImage(id);
|
return imageCache.getImage(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageID GfxDevice::addImageToCache(GPUImage img)
|
ImageID GfxDevice::addImageToCache(GPUImage img) {
|
||||||
{
|
|
||||||
return imageCache.addImage(std::move(img));
|
return imageCache.addImage(std::move(img));
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUImage GfxDevice::createImageRaw(
|
GPUImage GfxDevice::createImageRaw(
|
||||||
const vkutil::CreateImageInfo& createInfo,
|
const vkutil::CreateImageInfo& createInfo,
|
||||||
std::optional<VmaAllocationCreateInfo> customAllocationCreateInfo) const
|
std::optional<VmaAllocationCreateInfo> customAllocationCreateInfo) const {
|
||||||
{
|
|
||||||
std::uint32_t mipLevels = 1;
|
std::uint32_t mipLevels = 1;
|
||||||
if (createInfo.mipMap) {
|
if (createInfo.mipMap) {
|
||||||
const auto maxExtent = std::max(createInfo.extent.width, createInfo.extent.height);
|
const auto maxExtent = std::max(createInfo.extent.width, createInfo.extent.height);
|
||||||
@@ -452,9 +443,7 @@ GPUImage GfxDevice::createImageRaw(
|
|||||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||||
.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
};
|
};
|
||||||
const auto allocInfo = customAllocationCreateInfo.has_value() ?
|
const auto allocInfo = customAllocationCreateInfo.has_value() ? customAllocationCreateInfo.value() : defaultAllocInfo;
|
||||||
customAllocationCreateInfo.value() :
|
|
||||||
defaultAllocInfo;
|
|
||||||
|
|
||||||
GPUImage image{};
|
GPUImage image{};
|
||||||
image.format = createInfo.format;
|
image.format = createInfo.format;
|
||||||
@@ -464,8 +453,7 @@ GPUImage GfxDevice::createImageRaw(
|
|||||||
image.numLayers = createInfo.numLayers;
|
image.numLayers = createInfo.numLayers;
|
||||||
image.isCubemap = createInfo.isCubemap;
|
image.isCubemap = createInfo.isCubemap;
|
||||||
|
|
||||||
VK_CHECK(
|
VK_CHECK(vmaCreateImage(allocator, &imgInfo, &allocInfo, &image.image, &image.allocation, nullptr));
|
||||||
vmaCreateImage(allocator, &imgInfo, &allocInfo, &image.image, &image.allocation, nullptr));
|
|
||||||
|
|
||||||
// create view only when usage flags allow it
|
// create view only when usage flags allow it
|
||||||
bool shouldCreateView = ((createInfo.usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0) ||
|
bool shouldCreateView = ((createInfo.usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0) ||
|
||||||
@@ -475,12 +463,13 @@ GPUImage GfxDevice::createImageRaw(
|
|||||||
|
|
||||||
if (shouldCreateView) {
|
if (shouldCreateView) {
|
||||||
VkImageAspectFlags aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
|
VkImageAspectFlags aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
if (createInfo.format == VK_FORMAT_D32_SFLOAT) { // TODO: support other depth formats
|
if (createInfo.format == VK_FORMAT_D32_SFLOAT) {
|
||||||
|
// TODO: support other depth formats
|
||||||
aspectFlag = VK_IMAGE_ASPECT_DEPTH_BIT;
|
aspectFlag = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto viewType =
|
auto viewType =
|
||||||
createInfo.numLayers == 1 ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
createInfo.numLayers == 1 ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
if (createInfo.isCubemap && createInfo.numLayers == 6) {
|
if (createInfo.isCubemap && createInfo.numLayers == 6) {
|
||||||
viewType = VK_IMAGE_VIEW_TYPE_CUBE;
|
viewType = VK_IMAGE_VIEW_TYPE_CUBE;
|
||||||
}
|
}
|
||||||
@@ -491,13 +480,13 @@ GPUImage GfxDevice::createImageRaw(
|
|||||||
.viewType = viewType,
|
.viewType = viewType,
|
||||||
.format = createInfo.format,
|
.format = createInfo.format,
|
||||||
.subresourceRange =
|
.subresourceRange =
|
||||||
VkImageSubresourceRange{
|
VkImageSubresourceRange{
|
||||||
.aspectMask = aspectFlag,
|
.aspectMask = aspectFlag,
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
.levelCount = mipLevels,
|
.levelCount = mipLevels,
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = createInfo.numLayers,
|
.layerCount = createInfo.numLayers,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
VK_CHECK(vkCreateImageView(device, &viewCreateInfo, nullptr, &image.imageView));
|
VK_CHECK(vkCreateImageView(device, &viewCreateInfo, nullptr, &image.imageView));
|
||||||
@@ -506,104 +495,176 @@ GPUImage GfxDevice::createImageRaw(
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxDevice::uploadImageData(const GPUImage& image, void* pixelData, std::uint32_t layer) const
|
|
||||||
{
|
|
||||||
VkDeviceSize dataSize =
|
|
||||||
VkDeviceSize(image.extent.depth) *
|
|
||||||
image.extent.width *
|
|
||||||
image.extent.height *
|
|
||||||
BytesPerTexel(image.format);
|
|
||||||
|
|
||||||
auto uploadBuffer = createBuffer(dataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
|
||||||
memcpy(uploadBuffer.info.pMappedData, pixelData, size_t(dataSize));
|
|
||||||
|
|
||||||
executor.immediateSubmit([&](VkCommandBuffer cmd) {
|
|
||||||
assert(
|
|
||||||
(image.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) != 0 &&
|
|
||||||
"Image needs to have VK_IMAGE_USAGE_TRANSFER_DST_BIT to upload data to it");
|
|
||||||
vkutil::transitionImage(
|
|
||||||
cmd, image.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
|
||||||
|
|
||||||
const auto copyRegion = VkBufferImageCopy{
|
|
||||||
.bufferOffset = 0,
|
|
||||||
.bufferRowLength = 0,
|
|
||||||
.bufferImageHeight = 0,
|
|
||||||
.imageSubresource =
|
|
||||||
{
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.mipLevel = 0,
|
|
||||||
.baseArrayLayer = layer,
|
|
||||||
.layerCount = 1,
|
|
||||||
},
|
|
||||||
.imageExtent = image.extent,
|
|
||||||
};
|
|
||||||
|
|
||||||
vkCmdCopyBufferToImage(
|
|
||||||
cmd,
|
|
||||||
uploadBuffer.buffer,
|
|
||||||
image.image,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
1,
|
|
||||||
©Region);
|
|
||||||
|
|
||||||
if (image.mipLevels > 1) {
|
|
||||||
assert(
|
|
||||||
(image.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) != 0 &&
|
|
||||||
(image.usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0 &&
|
|
||||||
"Image needs to have VK_IMAGE_USAGE_TRANSFER_{DST,SRC}_BIT to generate mip maps");
|
|
||||||
// graphics::generateMipmaps(
|
|
||||||
// cmd,
|
|
||||||
// image.image,
|
|
||||||
// VkExtent2D{image.extent.width, image.extent.height},
|
|
||||||
// image.mipLevels);
|
|
||||||
spdlog::warn("Yea dawg, i ain't written this yet :pray:");
|
|
||||||
} else {
|
|
||||||
vkutil::transitionImage(
|
|
||||||
cmd,
|
|
||||||
image.image,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
destroyBuffer(uploadBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
GPUImage GfxDevice::loadImageFromFileRaw(
|
GPUImage GfxDevice::loadImageFromFileRaw(
|
||||||
const std::filesystem::path& path,
|
const std::filesystem::path& path,
|
||||||
VkFormat format,
|
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
bool mipMap) const
|
bool mipMap,
|
||||||
{
|
TextureIntent intent) const {
|
||||||
auto data = util::loadImage(path);
|
// 1) Decode file to CPU pixels (stb for png/jpg/hdr, tinyexr for exr)
|
||||||
if (!data.pixels) {
|
// IMPORTANT: util::loadImage should fill:
|
||||||
fmt::println("[error] failed to load image from '{}'", path.string());
|
// - width/height/channels(=4)
|
||||||
|
// - hdr + (pixels OR hdrPixels)
|
||||||
|
// - vkFormat (RGBA8_SRGB or RGBA8_UNORM or RGBA32F)
|
||||||
|
// - byteSize (exact bytes to upload)
|
||||||
|
const auto data = util::loadImage(path, intent);
|
||||||
|
if (data.vkFormat == VK_FORMAT_UNDEFINED || data.byteSize == 0 ||
|
||||||
|
(data.hdr ? (data.hdrPixels == nullptr) : (data.pixels == nullptr))) {
|
||||||
|
spdlog::error("Failed to load image '{}'", path.string());
|
||||||
return getImage(errorImageId);
|
return getImage(errorImageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2) Create GPU image using the format the loader chose (matches CPU memory layout)
|
||||||
auto image = createImageRaw({
|
auto image = createImageRaw({
|
||||||
.format = format,
|
.format = data.vkFormat,
|
||||||
.usage = usage | //
|
.usage = usage |
|
||||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | // for uploading pixel data to image
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // for generating mips
|
(mipMap ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : 0),
|
||||||
.extent =
|
.extent = VkExtent3D{
|
||||||
VkExtent3D{
|
.width = static_cast<std::uint32_t>(data.width),
|
||||||
.width = (std::uint32_t)data.width,
|
.height = static_cast<std::uint32_t>(data.height),
|
||||||
.height = (std::uint32_t)data.height,
|
.depth = 1,
|
||||||
.depth = 1,
|
},
|
||||||
},
|
|
||||||
.mipMap = mipMap,
|
.mipMap = mipMap,
|
||||||
});
|
});
|
||||||
uploadImageData(image, data.pixels);
|
|
||||||
|
|
||||||
|
// 3) Upload *exactly* byteSize bytes from the correct pointer
|
||||||
|
const void* src = data.hdr
|
||||||
|
? static_cast<const void*>(data.hdrPixels)
|
||||||
|
: static_cast<const void*>(data.pixels);
|
||||||
|
|
||||||
|
// Use the "sized" upload to avoid BytesPerTexel mismatches
|
||||||
|
uploadImageDataSized(image, src, data.byteSize, 0);
|
||||||
|
|
||||||
|
// 4) Debug label
|
||||||
image.debugName = path.string();
|
image.debugName = path.string();
|
||||||
vkutil::addDebugLabel(device, image.image, path.string().c_str());
|
vkutil::addDebugLabel(device, image.image, path.string().c_str());
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxDevice::destroyImage(const GPUImage& image) const
|
// void GfxDevice::uploadImageData(const GPUImage& image, void* pixelData, std::uint32_t layer) const {
|
||||||
{
|
// VkDeviceSize dataSize =
|
||||||
|
// VkDeviceSize(image.extent.depth) *
|
||||||
|
// image.extent.width *
|
||||||
|
// image.extent.height *
|
||||||
|
// BytesPerTexel(image.format);
|
||||||
|
//
|
||||||
|
// auto uploadBuffer = createBuffer(dataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||||
|
// memcpy(uploadBuffer.info.pMappedData, pixelData, size_t(dataSize));
|
||||||
|
//
|
||||||
|
// executor.immediateSubmit([&] (VkCommandBuffer cmd) {
|
||||||
|
// assert(
|
||||||
|
// (image.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) != 0 &&
|
||||||
|
// "Image needs to have VK_IMAGE_USAGE_TRANSFER_DST_BIT to upload data to it");
|
||||||
|
// vkutil::transitionImage(
|
||||||
|
// cmd, image.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
//
|
||||||
|
// const auto copyRegion = VkBufferImageCopy{
|
||||||
|
// .bufferOffset = 0,
|
||||||
|
// .bufferRowLength = 0,
|
||||||
|
// .bufferImageHeight = 0,
|
||||||
|
// .imageSubresource =
|
||||||
|
// {
|
||||||
|
// .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
// .mipLevel = 0,
|
||||||
|
// .baseArrayLayer = layer,
|
||||||
|
// .layerCount = 1,
|
||||||
|
// },
|
||||||
|
// .imageExtent = image.extent,
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// vkCmdCopyBufferToImage(
|
||||||
|
// cmd,
|
||||||
|
// uploadBuffer.buffer,
|
||||||
|
// image.image,
|
||||||
|
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
// 1,
|
||||||
|
// ©Region);
|
||||||
|
//
|
||||||
|
// if (image.mipLevels > 1) {
|
||||||
|
// assert(
|
||||||
|
// (image.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) != 0 &&
|
||||||
|
// (image.usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0 &&
|
||||||
|
// "Image needs to have VK_IMAGE_USAGE_TRANSFER_{DST,SRC}_BIT to generate mip maps");
|
||||||
|
// // graphics::generateMipmaps(
|
||||||
|
// // cmd,
|
||||||
|
// // image.image,
|
||||||
|
// // VkExtent2D{image.extent.width, image.extent.height},
|
||||||
|
// // image.mipLevels);
|
||||||
|
// spdlog::warn("Yea dawg, i ain't written this yet :pray:");
|
||||||
|
// } else {
|
||||||
|
// vkutil::transitionImage(
|
||||||
|
// cmd,
|
||||||
|
// image.image,
|
||||||
|
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
// VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// destroyBuffer(uploadBuffer);
|
||||||
|
// }
|
||||||
|
|
||||||
|
void GfxDevice::uploadImageDataSized(const GPUImage& image, const void* pixelData, std::size_t byteSize, std::uint32_t layer) const {
|
||||||
|
auto uploadBuffer = createBuffer(byteSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
|
||||||
|
|
||||||
|
// safety checks
|
||||||
|
assert(uploadBuffer.info.pMappedData);
|
||||||
|
assert(pixelData);
|
||||||
|
assert(byteSize > 0);
|
||||||
|
|
||||||
|
std::memcpy(uploadBuffer.info.pMappedData, pixelData, byteSize);
|
||||||
|
|
||||||
|
executor.immediateSubmit([&] (VkCommandBuffer cmd) {
|
||||||
|
vkutil::transitionImage(cmd, image.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
|
VkBufferImageCopy copyRegion{};
|
||||||
|
copyRegion.bufferOffset = 0;
|
||||||
|
copyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
copyRegion.imageSubresource.mipLevel = 0;
|
||||||
|
copyRegion.imageSubresource.baseArrayLayer = layer;
|
||||||
|
copyRegion.imageSubresource.layerCount = 1;
|
||||||
|
copyRegion.imageExtent = image.extent;
|
||||||
|
|
||||||
|
vkCmdCopyBufferToImage(cmd, uploadBuffer.buffer, image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Region);
|
||||||
|
|
||||||
|
vkutil::transitionImage(cmd, image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
});
|
||||||
|
|
||||||
|
destroyBuffer(uploadBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GPUImage GfxDevice::loadImageFromFileRaw(const std::filesystem::path& path, VkImageUsageFlags usage, bool mipMap) const {
|
||||||
|
// const auto data = util::loadImage(path);
|
||||||
|
// const bool isHdr = data.hdr && data.hdrPixels;
|
||||||
|
// const bool isLdr = !data.hdr && data.pixels;
|
||||||
|
//
|
||||||
|
// if (!isHdr && !isLdr || data.vkFormat == VK_FORMAT_UNDEFINED || data.byteSize == 0) {
|
||||||
|
// spdlog::error("failed to load image from '{}'", path.string());
|
||||||
|
// return getImage(errorImageId);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// auto image = createImageRaw({
|
||||||
|
// .format = data.vkFormat,
|
||||||
|
// .usage = usage |
|
||||||
|
// VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||||
|
// (mipMap ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : 0),
|
||||||
|
// .extent = VkExtent3D{
|
||||||
|
// .width = (std::uint32_t)data.width,
|
||||||
|
// .height = (std::uint32_t)data.height,
|
||||||
|
// .depth = 1,
|
||||||
|
// },
|
||||||
|
// .mipMap = mipMap,
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// const void* src = isHdr ? (const void*)data.hdrPixels : (const void*)data.pixels;
|
||||||
|
// uploadImageDataSized(image, src, data.byteSize, 0);
|
||||||
|
//
|
||||||
|
// image.debugName = path.string();
|
||||||
|
// vkutil::addDebugLabel(device, image.image, path.string().c_str());
|
||||||
|
// return image;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void GfxDevice::destroyImage(const GPUImage& image) const {
|
||||||
vkDestroyImageView(device, image.imageView, nullptr);
|
vkDestroyImageView(device, image.imageView, nullptr);
|
||||||
vmaDestroyImage(allocator, image.image, image.allocation);
|
vmaDestroyImage(allocator, image.image, image.allocation);
|
||||||
// TODO: if image has bindless id, update the set
|
// TODO: if image has bindless id, update the set
|
||||||
|
|||||||
@@ -7,20 +7,21 @@ ImageCache::ImageCache(GfxDevice& gfxDevice) : gfxDevice(gfxDevice)
|
|||||||
|
|
||||||
ImageID ImageCache::loadImageFromFile(
|
ImageID ImageCache::loadImageFromFile(
|
||||||
const std::filesystem::path& path,
|
const std::filesystem::path& path,
|
||||||
VkFormat format,
|
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
bool mipMap)
|
bool mipMap,
|
||||||
|
TextureIntent intent)
|
||||||
{
|
{
|
||||||
for (const auto& [id, info] : loadedImagesInfo) {
|
for (const auto& [id, info] : loadedImagesInfo) {
|
||||||
// TODO: calculate some hash to not have to linear search every time?
|
if (info.path == path &&
|
||||||
if (info.path == path && info.format == format && info.usage == usage &&
|
info.intent == intent &&
|
||||||
info.mipMap == mipMap) {
|
info.usage == usage &&
|
||||||
// std::cout << "Already loaded: " << path << std::endl;
|
info.mipMap == mipMap)
|
||||||
|
{
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto image = gfxDevice.loadImageFromFileRaw(path, format, usage, mipMap);
|
auto image = gfxDevice.loadImageFromFileRaw(path, usage, mipMap, intent);
|
||||||
if (image.isInitialized() && image.getBindlessId() == errorImageId) {
|
if (image.isInitialized() && image.getBindlessId() == errorImageId) {
|
||||||
return errorImageId;
|
return errorImageId;
|
||||||
}
|
}
|
||||||
@@ -32,10 +33,11 @@ ImageID ImageCache::loadImageFromFile(
|
|||||||
id,
|
id,
|
||||||
LoadedImageInfo{
|
LoadedImageInfo{
|
||||||
.path = path,
|
.path = path,
|
||||||
.format = format,
|
.intent = intent,
|
||||||
.usage = usage,
|
.usage = usage,
|
||||||
.mipMap = mipMap,
|
.mipMap = mipMap,
|
||||||
});
|
});
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +61,7 @@ ImageID ImageCache::addImage(ImageID id, GPUImage image)
|
|||||||
|
|
||||||
const GPUImage& ImageCache::getImage(ImageID id) const
|
const GPUImage& ImageCache::getImage(ImageID id) const
|
||||||
{
|
{
|
||||||
|
assert(id != NULL_IMAGE_ID && id < images.size());
|
||||||
return images.at(id);
|
return images.at(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,30 +2,118 @@
|
|||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
#include <tiny_gltf.h>
|
|
||||||
|
#define TINYEXR_IMPLEMENTATION
|
||||||
|
#include "tinyexr.h"
|
||||||
|
|
||||||
|
#include <cstdio> // fprintf
|
||||||
|
#include <cstdlib> // free
|
||||||
|
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
ImageData::~ImageData()
|
ImageData::~ImageData()
|
||||||
{
|
{
|
||||||
if (shouldSTBFree) {
|
if (shouldSTBFree) {
|
||||||
stbi_image_free(pixels);
|
if (pixels) stbi_image_free(pixels);
|
||||||
stbi_image_free(hdrPixels);
|
if (hdrPixels) stbi_image_free(hdrPixels);
|
||||||
|
spdlog::debug("Freed STB image memory");
|
||||||
|
}
|
||||||
|
if (shouldEXRFree) {
|
||||||
|
if (hdrPixels) free(hdrPixels);
|
||||||
|
spdlog::debug("Freed TinyEXR image memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
ImageData loadImage(const std::filesystem::path& p)
|
static bool isExrExt(const std::filesystem::path& p)
|
||||||
|
{
|
||||||
|
auto ext = p.extension().string();
|
||||||
|
for (auto& c : ext) c = char(::tolower(c));
|
||||||
|
return ext == ".exr";
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageData loadImage(const std::filesystem::path& p, TextureIntent intent)
|
||||||
{
|
{
|
||||||
ImageData data;
|
ImageData data;
|
||||||
|
|
||||||
|
// ---------- EXR ----------
|
||||||
|
if (isExrExt(p)) {
|
||||||
|
float* out = nullptr;
|
||||||
|
int w = 0, h = 0;
|
||||||
|
const char* err = nullptr;
|
||||||
|
|
||||||
|
const int ret = LoadEXR(&out, &w, &h, p.string().c_str(), &err);
|
||||||
|
if (ret != TINYEXR_SUCCESS || !out || w <= 0 || h <= 0) {
|
||||||
|
if (err) {
|
||||||
|
spdlog::error("TinyEXR error: {}", err);
|
||||||
|
FreeEXRErrorMessage(err);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
data.hdr = true;
|
||||||
|
data.hdrPixels = out;
|
||||||
|
data.width = w;
|
||||||
|
data.height = h;
|
||||||
|
data.channels = 4;
|
||||||
|
data.shouldEXRFree = true;
|
||||||
|
|
||||||
|
data.vkFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||||
|
data.byteSize = std::size_t(w) * std::size_t(h) * 4 * sizeof(float);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- STB HDR (.hdr etc) ----------
|
||||||
data.shouldSTBFree = true;
|
data.shouldSTBFree = true;
|
||||||
|
|
||||||
if (stbi_is_hdr(p.string().c_str())) {
|
if (stbi_is_hdr(p.string().c_str())) {
|
||||||
data.hdr = true;
|
data.hdr = true;
|
||||||
data.hdrPixels = stbi_loadf(p.string().c_str(), &data.width, &data.height, &data.comp, 4);
|
data.hdrPixels = stbi_loadf(
|
||||||
} else {
|
p.string().c_str(),
|
||||||
data.pixels = stbi_load(p.string().c_str(), &data.width, &data.height, &data.channels, 4);
|
&data.width,
|
||||||
|
&data.height,
|
||||||
|
&data.comp,
|
||||||
|
4
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!data.hdrPixels || data.width <= 0 || data.height <= 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
data.channels = 4;
|
||||||
|
data.vkFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||||
|
data.byteSize = std::size_t(data.width) * std::size_t(data.height) * 4 * sizeof(float);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- STB LDR (png/jpg/...) ----------
|
||||||
|
data.pixels = stbi_load(
|
||||||
|
p.string().c_str(),
|
||||||
|
&data.width,
|
||||||
|
&data.height,
|
||||||
|
&data.channels,
|
||||||
|
4
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!data.pixels || data.width <= 0 || data.height <= 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
data.channels = 4;
|
data.channels = 4;
|
||||||
|
|
||||||
|
// Choose color space for LDR based on intent
|
||||||
|
switch (intent) {
|
||||||
|
case TextureIntent::ColorSrgb:
|
||||||
|
data.vkFormat = VK_FORMAT_R8G8B8A8_SRGB;
|
||||||
|
break;
|
||||||
|
case TextureIntent::DataLinear:
|
||||||
|
data.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.byteSize = std::size_t(data.width) * std::size_t(data.height) * 4 * sizeof(unsigned char);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ void GameRenderer::init(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameRenderer::beginDrawing(GfxDevice& gfxDevice) {
|
void GameRenderer::beginDrawing(GfxDevice& gfxDevice) {
|
||||||
|
flushMaterialUpdates(gfxDevice);
|
||||||
meshDrawCommands.clear();
|
meshDrawCommands.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,8 +48,13 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
|
|||||||
.fogDensity = sceneData.fogDensity,
|
.fogDensity = sceneData.fogDensity,
|
||||||
.materialsBuffer = materialCache.getMaterialDataBufferAddress(),
|
.materialsBuffer = materialCache.getMaterialDataBufferAddress(),
|
||||||
};
|
};
|
||||||
sceneDataBuffer.uploadNewData(
|
vkutil::bufferHostWriteToShaderReadBarrier(
|
||||||
cmd, gfxDevice.getCurrentFrameIndex(), (void*)&gpuSceneData, sizeof(GPUSceneData));
|
cmd,
|
||||||
|
materialCache.getMaterialDataBuffer().buffer,
|
||||||
|
0,
|
||||||
|
VK_WHOLE_SIZE
|
||||||
|
);
|
||||||
|
sceneDataBuffer.uploadNewData(cmd, gfxDevice.getCurrentFrameIndex(), (void*)&gpuSceneData, sizeof(GPUSceneData));
|
||||||
|
|
||||||
const auto& drawImage = gfxDevice.getImage(drawImageId);
|
const auto& drawImage = gfxDevice.getImage(drawImageId);
|
||||||
const auto& depthImage = gfxDevice.getImage(depthImageId);
|
const auto& depthImage = gfxDevice.getImage(depthImageId);
|
||||||
@@ -122,7 +128,7 @@ Material& GameRenderer::getMaterialMutable(MaterialID id) {
|
|||||||
|
|
||||||
void GameRenderer::updateMaterialGPU(MaterialID id) {
|
void GameRenderer::updateMaterialGPU(MaterialID id) {
|
||||||
assert(id != NULL_MATERIAL_ID);
|
assert(id != NULL_MATERIAL_ID);
|
||||||
materialCache.updateMaterialGPU(GameState::GetInstance().Gfx(), id);
|
pendingMaterialUploads.push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameRenderer::setSkyboxTexture(ImageID skyboxImageId) {
|
void GameRenderer::setSkyboxTexture(ImageID skyboxImageId) {
|
||||||
@@ -130,6 +136,14 @@ void GameRenderer::setSkyboxTexture(ImageID skyboxImageId) {
|
|||||||
skyboxPipeline->setSkyboxImage(skyboxImageId);
|
skyboxPipeline->setSkyboxImage(skyboxImageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameRenderer::flushMaterialUpdates(GfxDevice& gfxDevice) {
|
||||||
|
for (MaterialID id : pendingMaterialUploads) {
|
||||||
|
materialCache.updateMaterialGPU(gfxDevice, id);
|
||||||
|
// if non-coherent: flush mapped range for that id here
|
||||||
|
}
|
||||||
|
pendingMaterialUploads.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void GameRenderer::createDrawImage(GfxDevice& gfxDevice,
|
void GameRenderer::createDrawImage(GfxDevice& gfxDevice,
|
||||||
const glm::ivec2& drawImageSize,
|
const glm::ivec2& drawImageSize,
|
||||||
bool firstCreate)
|
bool firstCreate)
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ CubeMap::~CubeMap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CubeMap::LoadCubeMap(const std::filesystem::path& directoryPath) {
|
void CubeMap::LoadCubeMap(const std::filesystem::path& directoryPath) {
|
||||||
m_hdrImage = GameState::GetInstance().Gfx().loadImageFromFile(directoryPath, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, false);
|
// m_hdrImage = GameState::GetInstance().Gfx().loadImageFromFile(directoryPath, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, false);
|
||||||
|
m_hdrImage = GameState::GetInstance().Gfx().loadImageFromFile(directoryPath, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeMap::RenderToCubemap(ImageID inputImage,
|
void CubeMap::RenderToCubemap(ImageID inputImage,
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ void vkutil::transitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayout c
|
|||||||
VkImageAspectFlags aspectMask =
|
VkImageAspectFlags aspectMask =
|
||||||
(currentLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ||
|
(currentLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ||
|
||||||
newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ||
|
newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ||
|
||||||
newLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) ?
|
newLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
|
||||||
VK_IMAGE_ASPECT_DEPTH_BIT :
|
? VK_IMAGE_ASPECT_DEPTH_BIT
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT;
|
: VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
VkImageMemoryBarrier2 imageBarrier{
|
VkImageMemoryBarrier2 imageBarrier{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
||||||
@@ -81,6 +81,27 @@ void vkutil::copyImageToImage(VkCommandBuffer cmd, VkImage source, VkImage desti
|
|||||||
vkCmdBlitImage2(cmd, &blitInfo);
|
vkCmdBlitImage2(cmd, &blitInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vkutil::bufferHostWriteToShaderReadBarrier(
|
||||||
|
VkCommandBuffer cmd, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size) {
|
||||||
|
VkBufferMemoryBarrier2 barrier{VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2};
|
||||||
|
barrier.srcStageMask = VK_PIPELINE_STAGE_2_HOST_BIT;
|
||||||
|
barrier.srcAccessMask = VK_ACCESS_2_HOST_WRITE_BIT;
|
||||||
|
barrier.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT |
|
||||||
|
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
|
||||||
|
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT;
|
||||||
|
barrier.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT;
|
||||||
|
barrier.buffer = buffer;
|
||||||
|
barrier.offset = offset;
|
||||||
|
barrier.size = size;
|
||||||
|
|
||||||
|
VkDependencyInfo dep{VK_STRUCTURE_TYPE_DEPENDENCY_INFO};
|
||||||
|
dep.bufferMemoryBarrierCount = 1;
|
||||||
|
dep.pBufferMemoryBarriers = &barrier;
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier2(cmd, &dep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void vkutil::addDebugLabel(VkDevice device, VkImage image, const char* label) {
|
void vkutil::addDebugLabel(VkDevice device, VkImage image, const char* label) {
|
||||||
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
@@ -135,8 +156,7 @@ vkutil::RenderInfo vkutil::createRenderingInfo(const RenderingInfoParams& params
|
|||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
.imageView = params.colorImageView,
|
.imageView = params.colorImageView,
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
.loadOp = params.colorImageClearValue ? VK_ATTACHMENT_LOAD_OP_CLEAR :
|
.loadOp = params.colorImageClearValue ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
|
||||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
};
|
};
|
||||||
if (params.colorImageClearValue) {
|
if (params.colorImageClearValue) {
|
||||||
@@ -150,8 +170,7 @@ vkutil::RenderInfo vkutil::createRenderingInfo(const RenderingInfoParams& params
|
|||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
.imageView = params.depthImageView,
|
.imageView = params.depthImageView,
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
||||||
.loadOp = params.depthImageClearValue ? VK_ATTACHMENT_LOAD_OP_CLEAR :
|
.loadOp = params.depthImageClearValue ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
|
||||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
};
|
};
|
||||||
if (params.depthImageClearValue) {
|
if (params.depthImageClearValue) {
|
||||||
@@ -162,10 +181,10 @@ vkutil::RenderInfo vkutil::createRenderingInfo(const RenderingInfoParams& params
|
|||||||
ri.renderingInfo = VkRenderingInfo{
|
ri.renderingInfo = VkRenderingInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||||
.renderArea =
|
.renderArea =
|
||||||
VkRect2D{
|
VkRect2D{
|
||||||
.offset = {},
|
.offset = {},
|
||||||
.extent = params.renderExtent,
|
.extent = params.renderExtent,
|
||||||
},
|
},
|
||||||
.layerCount = 1,
|
.layerCount = 1,
|
||||||
.colorAttachmentCount = params.colorImageView ? 1u : 0u,
|
.colorAttachmentCount = params.colorImageView ? 1u : 0u,
|
||||||
.pColorAttachments = params.colorImageView ? &ri.colorAttachment : nullptr,
|
.pColorAttachments = params.colorImageView ? &ri.colorAttachment : nullptr,
|
||||||
@@ -203,8 +222,7 @@ VkShaderModule vkutil::loadShaderModule(const std::filesystem::path& path, VkDev
|
|||||||
return shaderModule;
|
return shaderModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDebugLabel(VkDevice device, VkImage image, const char* label)
|
void addDebugLabel(VkDevice device, VkImage image, const char* label) {
|
||||||
{
|
|
||||||
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
.objectType = VK_OBJECT_TYPE_IMAGE,
|
.objectType = VK_OBJECT_TYPE_IMAGE,
|
||||||
@@ -214,8 +232,7 @@ void addDebugLabel(VkDevice device, VkImage image, const char* label)
|
|||||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDebugLabel(VkDevice device, VkImageView imageView, const char* label)
|
void addDebugLabel(VkDevice device, VkImageView imageView, const char* label) {
|
||||||
{
|
|
||||||
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
.objectType = VK_OBJECT_TYPE_IMAGE_VIEW,
|
.objectType = VK_OBJECT_TYPE_IMAGE_VIEW,
|
||||||
@@ -225,8 +242,7 @@ void addDebugLabel(VkDevice device, VkImageView imageView, const char* label)
|
|||||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDebugLabel(VkDevice device, VkShaderModule shaderModule, const char* label)
|
void addDebugLabel(VkDevice device, VkShaderModule shaderModule, const char* label) {
|
||||||
{
|
|
||||||
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
.objectType = VK_OBJECT_TYPE_SHADER_MODULE,
|
.objectType = VK_OBJECT_TYPE_SHADER_MODULE,
|
||||||
@@ -236,8 +252,7 @@ void addDebugLabel(VkDevice device, VkShaderModule shaderModule, const char* lab
|
|||||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDebugLabel(VkDevice device, VkPipeline pipeline, const char* label)
|
void addDebugLabel(VkDevice device, VkPipeline pipeline, const char* label) {
|
||||||
{
|
|
||||||
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
.objectType = VK_OBJECT_TYPE_PIPELINE,
|
.objectType = VK_OBJECT_TYPE_PIPELINE,
|
||||||
@@ -247,8 +262,7 @@ void addDebugLabel(VkDevice device, VkPipeline pipeline, const char* label)
|
|||||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDebugLabel(VkDevice device, VkPipelineLayout layout, const char* label)
|
void addDebugLabel(VkDevice device, VkPipelineLayout layout, const char* label) {
|
||||||
{
|
|
||||||
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
.objectType = VK_OBJECT_TYPE_PIPELINE_LAYOUT,
|
.objectType = VK_OBJECT_TYPE_PIPELINE_LAYOUT,
|
||||||
@@ -258,8 +272,7 @@ void addDebugLabel(VkDevice device, VkPipelineLayout layout, const char* label)
|
|||||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDebugLabel(VkDevice device, VkBuffer buffer, const char* label)
|
void addDebugLabel(VkDevice device, VkBuffer buffer, const char* label) {
|
||||||
{
|
|
||||||
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
.objectType = VK_OBJECT_TYPE_BUFFER,
|
.objectType = VK_OBJECT_TYPE_BUFFER,
|
||||||
@@ -269,8 +282,7 @@ void addDebugLabel(VkDevice device, VkBuffer buffer, const char* label)
|
|||||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDebugLabel(VkDevice device, VkSampler sampler, const char* label)
|
void addDebugLabel(VkDevice device, VkSampler sampler, const char* label) {
|
||||||
{
|
|
||||||
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
.objectType = VK_OBJECT_TYPE_SAMPLER,
|
.objectType = VK_OBJECT_TYPE_SAMPLER,
|
||||||
@@ -280,8 +292,7 @@ void addDebugLabel(VkDevice device, VkSampler sampler, const char* label)
|
|||||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkutil::RenderInfo createRenderingInfo(const vkutil::RenderingInfoParams& params)
|
vkutil::RenderInfo createRenderingInfo(const vkutil::RenderingInfoParams& params) {
|
||||||
{
|
|
||||||
assert(
|
assert(
|
||||||
(params.colorImageView || params.depthImageView != nullptr) &&
|
(params.colorImageView || params.depthImageView != nullptr) &&
|
||||||
"Either draw or depth image should be present");
|
"Either draw or depth image should be present");
|
||||||
@@ -295,8 +306,7 @@ vkutil::RenderInfo createRenderingInfo(const vkutil::RenderingInfoParams& params
|
|||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
.imageView = params.colorImageView,
|
.imageView = params.colorImageView,
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
.loadOp = params.colorImageClearValue ? VK_ATTACHMENT_LOAD_OP_CLEAR :
|
.loadOp = params.colorImageClearValue ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
|
||||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
};
|
};
|
||||||
if (params.colorImageClearValue) {
|
if (params.colorImageClearValue) {
|
||||||
@@ -310,8 +320,7 @@ vkutil::RenderInfo createRenderingInfo(const vkutil::RenderingInfoParams& params
|
|||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
.imageView = params.depthImageView,
|
.imageView = params.depthImageView,
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
||||||
.loadOp = params.depthImageClearValue ? VK_ATTACHMENT_LOAD_OP_CLEAR :
|
.loadOp = params.depthImageClearValue ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
|
||||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
};
|
};
|
||||||
if (params.depthImageClearValue) {
|
if (params.depthImageClearValue) {
|
||||||
@@ -322,10 +331,10 @@ vkutil::RenderInfo createRenderingInfo(const vkutil::RenderingInfoParams& params
|
|||||||
ri.renderingInfo = VkRenderingInfo{
|
ri.renderingInfo = VkRenderingInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||||
.renderArea =
|
.renderArea =
|
||||||
VkRect2D{
|
VkRect2D{
|
||||||
.offset = {},
|
.offset = {},
|
||||||
.extent = params.renderExtent,
|
.extent = params.renderExtent,
|
||||||
},
|
},
|
||||||
.layerCount = 1,
|
.layerCount = 1,
|
||||||
.colorAttachmentCount = params.colorImageView ? 1u : 0u,
|
.colorAttachmentCount = params.colorImageView ? 1u : 0u,
|
||||||
.pColorAttachments = params.colorImageView ? &ri.colorAttachment : nullptr,
|
.pColorAttachments = params.colorImageView ? &ri.colorAttachment : nullptr,
|
||||||
|
|||||||
5
destrum/third_party/CMakeLists.txt
vendored
5
destrum/third_party/CMakeLists.txt
vendored
@@ -52,4 +52,7 @@ add_subdirectory(json)
|
|||||||
|
|
||||||
add_subdirectory(spdlog)
|
add_subdirectory(spdlog)
|
||||||
|
|
||||||
add_subdirectory(tinygltf)
|
add_subdirectory(tinygltf)
|
||||||
|
|
||||||
|
add_subdirectory(tinyexr)
|
||||||
|
target_include_directories(tinyexr PUBLIC "${CMAKE_CURRENT_LIST_DIR}/tinyexr")
|
||||||
|
|||||||
1
destrum/third_party/tinyexr
vendored
Submodule
1
destrum/third_party/tinyexr
vendored
Submodule
Submodule destrum/third_party/tinyexr added at 90a147c711
BIN
lightkeeper/assets_src/starmap_2020_4k.exr
Normal file
BIN
lightkeeper/assets_src/starmap_2020_4k.exr
Normal file
Binary file not shown.
BIN
lightkeeper/assets_src/starmap_2020_8k.exr
Normal file
BIN
lightkeeper/assets_src/starmap_2020_8k.exr
Normal file
Binary file not shown.
@@ -25,20 +25,13 @@ void LightKeeper::customInit() {
|
|||||||
const float aspectRatio = static_cast<float>(m_params.renderSize.x) / static_cast<float>(m_params.renderSize.y);
|
const float aspectRatio = static_cast<float>(m_params.renderSize.x) / static_cast<float>(m_params.renderSize.y);
|
||||||
camera.setAspectRatio(aspectRatio);
|
camera.setAspectRatio(aspectRatio);
|
||||||
|
|
||||||
auto file = AssetFS::GetInstance().ReadBytes("engine://assetfstest.txt");
|
|
||||||
std::string fileStr(file.begin(), file.end());
|
|
||||||
spdlog::info("Read from assetfstest.txt: {}", fileStr);
|
|
||||||
testMesh.name = "Test Mesh";
|
testMesh.name = "Test Mesh";
|
||||||
// testMesh.vertices = vertices;
|
|
||||||
// testMesh.indices = indices;
|
|
||||||
|
|
||||||
auto list_of_models = ModelLoader::LoadGLTF_CPUMeshes_MergedPerMesh(AssetFS::GetInstance().GetFullPath("game://kitty.glb").generic_string());
|
auto list_of_models = ModelLoader::LoadGLTF_CPUMeshes_MergedPerMesh(AssetFS::GetInstance().GetFullPath("game://kitty.glb").generic_string());
|
||||||
testMesh = list_of_models[0];
|
testMesh = list_of_models[0];
|
||||||
testMeshID = meshCache.addMesh(gfxDevice, testMesh);
|
testMeshID = meshCache.addMesh(gfxDevice, testMesh);
|
||||||
spdlog::info("TestMesh uploaded with id: {}", testMeshID);
|
spdlog::info("TestMesh uploaded with id: {}", testMeshID);
|
||||||
|
|
||||||
const auto testimgpath = AssetFS::GetInstance().GetFullPath("game://kitty.png");
|
auto testimgID = gfxDevice.loadImageFromFile(AssetFS::GetInstance().GetFullPath("game://kitty.png"));
|
||||||
auto testimgID = gfxDevice.loadImageFromFile(testimgpath);
|
|
||||||
spdlog::info("Test image loaded with id: {}", testimgID);
|
spdlog::info("Test image loaded with id: {}", testimgID);
|
||||||
testMaterialID = materialCache.addMaterial(gfxDevice, {
|
testMaterialID = materialCache.addMaterial(gfxDevice, {
|
||||||
.baseColor = glm::vec3(1.f),
|
.baseColor = glm::vec3(1.f),
|
||||||
@@ -46,8 +39,6 @@ void LightKeeper::customInit() {
|
|||||||
});
|
});
|
||||||
spdlog::info("Test material created with id: {}", testMaterialID);
|
spdlog::info("Test material created with id: {}", testMaterialID);
|
||||||
|
|
||||||
renderer.setSkyboxTexture(testimgID);
|
|
||||||
|
|
||||||
camera.SetRotation(glm::radians(glm::vec2(90.f, 0.f)));
|
camera.SetRotation(glm::radians(glm::vec2(90.f, 0.f)));
|
||||||
|
|
||||||
auto& scene = SceneManager::GetInstance().CreateScene("Main");
|
auto& scene = SceneManager::GetInstance().CreateScene("Main");
|
||||||
@@ -55,7 +46,26 @@ void LightKeeper::customInit() {
|
|||||||
auto testCube = std::make_shared<GameObject>("TestCube");
|
auto testCube = std::make_shared<GameObject>("TestCube");
|
||||||
auto meshComp = testCube->AddComponent<MeshRendererComponent>();
|
auto meshComp = testCube->AddComponent<MeshRendererComponent>();
|
||||||
meshComp->SetMeshID(testMeshID);
|
meshComp->SetMeshID(testMeshID);
|
||||||
meshComp->SetMaterialID(testMaterialID);
|
meshComp->SetMaterialID(testMaterialID);const int count = 100;
|
||||||
|
const float radius = 5.0f;
|
||||||
|
|
||||||
|
const float orbitRadius = 5.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
auto childCube = std::make_shared<GameObject>(fmt::format("ChildCube{}", i));
|
||||||
|
|
||||||
|
auto childMeshComp = childCube->AddComponent<MeshRendererComponent>();
|
||||||
|
childMeshComp->SetMeshID(testMeshID);
|
||||||
|
childMeshComp->SetMaterialID(testMaterialID);
|
||||||
|
|
||||||
|
childCube->GetTransform().SetWorldScale(glm::vec3(0.1f));
|
||||||
|
|
||||||
|
// Add orbit + self spin
|
||||||
|
auto orbit = childCube->AddComponent<OrbitAndSpin>(orbitRadius, glm::vec3(0.0f));
|
||||||
|
orbit->Randomize(1337u + (uint32_t)i); // stable random per index
|
||||||
|
|
||||||
|
scene.Add(childCube);
|
||||||
|
}
|
||||||
testCube->AddComponent<Spinner>(glm::vec3(0, 1, 0), glm::radians(10.0f)); // spin around Y, rad/sec
|
testCube->AddComponent<Spinner>(glm::vec3(0, 1, 0), glm::radians(10.0f)); // spin around Y, rad/sec
|
||||||
//rotate 180 around X axis
|
//rotate 180 around X axis
|
||||||
testCube->GetTransform().SetLocalRotation(glm::quat(glm::vec3(glm::radians(180.0f), 0.0f, 0.0f)));
|
testCube->GetTransform().SetLocalRotation(glm::quat(glm::vec3(glm::radians(180.0f), 0.0f, 0.0f)));
|
||||||
@@ -65,46 +75,25 @@ void LightKeeper::customInit() {
|
|||||||
globeRoot->AddComponent<Spinner>(glm::vec3(0, 1, 0), 1.0f); // spin around Y, rad/sec
|
globeRoot->AddComponent<Spinner>(glm::vec3(0, 1, 0), 1.0f); // spin around Y, rad/sec
|
||||||
scene.Add(globeRoot);
|
scene.Add(globeRoot);
|
||||||
|
|
||||||
// const int count = 100;
|
|
||||||
// const float radius = 5.0f;
|
|
||||||
//
|
|
||||||
// const float orbitRadius = 5.0f;
|
|
||||||
//
|
|
||||||
// for (int i = 0; i < count; ++i) {
|
|
||||||
// auto childCube = std::make_shared<GameObject>(fmt::format("ChildCube{}", i));
|
|
||||||
//
|
|
||||||
// auto childMeshComp = childCube->AddComponent<MeshRendererComponent>();
|
|
||||||
// childMeshComp->SetMeshID(testMeshID);
|
|
||||||
// childMeshComp->SetMaterialID(testMaterialID);
|
|
||||||
//
|
|
||||||
// childCube->GetTransform().SetWorldScale(glm::vec3(0.1f));
|
|
||||||
//
|
|
||||||
// // Add orbit + self spin
|
|
||||||
// auto orbit = childCube->AddComponent<OrbitAndSpin>(orbitRadius, glm::vec3(0.0f));
|
|
||||||
// orbit->Randomize(1337u + (uint32_t)i); // stable random per index
|
|
||||||
//
|
|
||||||
// scene.Add(childCube);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// testCube->AddComponent<Rotator>(10, 5);
|
|
||||||
|
|
||||||
|
|
||||||
scene.Add(testCube);
|
scene.Add(testCube);
|
||||||
|
|
||||||
// const auto skyboxID = AssetFS::GetInstance().GetFullPath("engine://textures/skybox.jpg");
|
// const auto skyboxID = AssetFS::GetInstance().GetFullPath("engine://textures/skybox.jpg");
|
||||||
const auto skyboxID = AssetFS::GetInstance().GetFullPath("engine://textures/test-skybox.png");
|
// const auto skyboxID = AssetFS::GetInstance().GetFullPath("engine://textures/mars.jpg");
|
||||||
auto skyboxIDs = gfxDevice.loadImageFromFile(testimgpath);
|
const auto skyboxID = AssetFS::GetInstance().GetCookedPathForFile("game://starmap_2020_4k.exr");
|
||||||
|
//
|
||||||
|
// const auto skyboxID = AssetFS::GetInstance().GetFullPath("engine://textures/test-skybox.png");
|
||||||
|
//
|
||||||
const auto vertShaderPath = AssetFS::GetInstance().GetCookedPathForFile("engine://shaders/cubemap.vert");
|
const auto vertShaderPath = AssetFS::GetInstance().GetCookedPathForFile("engine://shaders/cubemap.vert");
|
||||||
const auto fragShaderPath = AssetFS::GetInstance().GetCookedPathForFile("engine://shaders/cubemap.frag");
|
const auto fragShaderPath = AssetFS::GetInstance().GetCookedPathForFile("engine://shaders/cubemap.frag");
|
||||||
|
//
|
||||||
skyboxCubemap = std::make_unique<CubeMap>();
|
skyboxCubemap = std::make_unique<CubeMap>();
|
||||||
skyboxCubemap->LoadCubeMap(skyboxID.generic_string());
|
skyboxCubemap->LoadCubeMap(skyboxID.generic_string());
|
||||||
skyboxCubemap->InitCubemapPipeline(vertShaderPath.generic_string(), fragShaderPath.generic_string());
|
skyboxCubemap->InitCubemapPipeline(vertShaderPath.generic_string(), fragShaderPath.generic_string());
|
||||||
skyboxCubemap->CreateCubeMap();
|
skyboxCubemap->CreateCubeMap();
|
||||||
|
|
||||||
renderer.setSkyboxTexture(skyboxCubemap->GetCubeMapImageID());
|
renderer.setSkyboxTexture(skyboxCubemap->GetCubeMapImageID());
|
||||||
// skyboxCubemap->CreateCubeMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightKeeper::customUpdate(float dt) {
|
void LightKeeper::customUpdate(float dt) {
|
||||||
|
|||||||
Reference in New Issue
Block a user