a little bit more reformatting

This commit is contained in:
bailehuni 2024-06-04 23:31:22 +01:00
parent 9b5fca62f5
commit 71e7f51195
27 changed files with 517 additions and 490 deletions

View File

@ -22,7 +22,7 @@ set(SRC_FILES
"src/file_dialog.cpp"
"src/files.cpp"
"src/gen_tangents.cpp"
"src/gfx_device_vulkan.cpp"
"src/gfx_device.cpp"
"src/gltf_loader.cpp"
"src/input_manager.cpp"
"src/renderer.cpp"

46
CMakePresets.json Normal file
View File

@ -0,0 +1,46 @@
{
"version": 3,
"configurePresets": [
{
"name": "windows-base",
"description": "Target Windows with the Visual Studio development environment.",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "x64-debug",
"displayName": "x64 Debug",
"description": "Target Windows (64-bit) with the Visual Studio development environment. (Debug)",
"inherits": "windows-base",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"ENGINETEST_BUILD_WIN32_APP": "OFF"
}
},
{
"name": "x64-release",
"displayName": "x64 Release",
"description": "Target Windows (64-bit) with the Visual Studio development environment. (RelWithDebInfo)",
"inherits": "x64-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"ENGINETEST_BUILD_WIN32_APP": "ON"
}
}
]
}

View File

@ -9,21 +9,21 @@
namespace engine {
enum class EventSubscriberKind {
kEntity,
ENTITY,
};
// Event handler base-class
template <typename T>
class EventHandler {
public:
virtual void OnEvent(T data) = 0;
virtual void onEvent(T data) = 0;
};
// Event queue interface to allow for different type queues to be in the map
class IEventQueue {
public:
virtual ~IEventQueue() {}
virtual void DespatchEvents() = 0;
virtual void despatchEvents() = 0;
};
template <typename T>
@ -31,42 +31,40 @@ class EventQueue : public IEventQueue {
// holds events of type T and subscribers to those events
public:
void Subscribe(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler)
void subscribe(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler)
{
// For the time being, ignore kind (TODO)
(void)kind;
assert(subscribers_.contains(id) == false && "subscribing to an event with ID that's already in use!");
subscribers_.emplace(id, handler);
assert(m_subscribers.contains(id) == false && "subscribing to an event with ID that's already in use!");
m_subscribers.emplace(id, handler);
}
void QueueEvent(EventSubscriberKind kind, uint32_t id, T event)
void queueEvent(EventSubscriberKind kind, uint32_t id, T event)
{
// For the time being, ignore kind (TODO)
(void)kind;
assert(subscribers_.contains(id) && "Attempt to submit event to non-existing subscriber!");
EventHandler<T>* handler = subscribers_.at(id);
event_queue_.emplace(handler, event);
assert(m_subscribers.contains(id) && "Attempt to submit event to non-existing subscriber!");
EventHandler<T>* handler = m_subscribers.at(id);
m_event_queue.emplace(handler, event);
}
void DespatchEvents() override
void despatchEvents() override
{
while (event_queue_.empty() == false) {
auto [handler, event] = event_queue_.front();
handler->OnEvent(event);
event_queue_.pop();
while (m_event_queue.empty() == false) {
auto [handler, event] = m_event_queue.front();
handler->onEvent(event);
m_event_queue.pop();
}
}
private:
std::unordered_map<uint32_t, EventHandler<T>*> subscribers_;
std::unordered_map<uint32_t, EventHandler<T>*> m_subscribers;
struct QueuedEvent {
QueuedEvent(EventHandler<T>* handler, T event) : handler(handler), event(event) {}
EventHandler<T>* handler;
T event;
};
std::queue<QueuedEvent> event_queue_{};
std::queue<QueuedEvent> m_event_queue{};
};
class EventSystem {
@ -77,42 +75,42 @@ class EventSystem {
~EventSystem() {}
template <typename T>
void RegisterEventType()
void registerEventType()
{
size_t hash = typeid(T).hash_code();
assert(event_queues_.contains(hash) == false && "Registering an event queue more than once!");
event_queues_.emplace(hash, std::make_unique<EventQueue<T>>());
assert(m_event_queues.contains(hash) == false && "Registering an event queue more than once!");
m_event_queues.emplace(hash, std::make_unique<EventQueue<T>>());
}
template <typename T>
void SubscribeToEventType(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler)
void subscribeToEventType(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler)
{
size_t hash = typeid(T).hash_code();
assert(event_queues_.contains(hash) && "Subscribing to event type that isn't registered!");
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(event_queues_.at(hash).get());
assert(m_event_queues.contains(hash) && "Subscribing to event type that isn't registered!");
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(m_event_queues.at(hash).get());
assert(queue != nullptr && "This cast should work?!! wot");
queue->Subscribe(kind, id, handler);
queue->subscribe(kind, id, handler);
}
template <typename T>
void QueueEvent(EventSubscriberKind kind, uint32_t subscriber_id, T event)
void queueEvent(EventSubscriberKind kind, uint32_t subscriber_id, T event)
{
size_t hash = typeid(T).hash_code();
assert(event_queues_.contains(hash) && "Subscribing to event type that isn't registered!");
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(event_queues_.at(hash).get());
assert(m_event_queues.contains(hash) && "Subscribing to event type that isn't registered!");
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(m_event_queues.at(hash).get());
assert(queue != nullptr && "This cast should work?!! wot");
queue->QueueEvent(kind, subscriber_id, event);
queue->queueEvent(kind, subscriber_id, event);
}
void DespatchEvents()
void despatchEvents()
{
for (auto& [hash, queue] : event_queues_) {
queue->DespatchEvents();
for (auto& [hash, queue] : m_event_queues) {
queue->despatchEvents();
}
}
private:
std::unordered_map<size_t, std::unique_ptr<IEventQueue>> event_queues_{};
std::unordered_map<size_t, std::unique_ptr<IEventQueue>> m_event_queues{};
};
} // namespace engine

View File

@ -4,8 +4,8 @@
#include <string>
#include <vector>
namespace engine::util {
namespace engine {
std::filesystem::path OpenFileDialog(const std::vector<std::string>& extensions);
std::filesystem::path openFileDialog(const std::vector<std::string>& extensions);
} // namespace engine::util
} // namespace engine

View File

@ -8,11 +8,11 @@
namespace engine {
std::unique_ptr<std::vector<char>> ReadTextFile(const std::string& path);
std::unique_ptr<std::vector<uint8_t>> ReadBinaryFile(const std::string& path);
std::unique_ptr<std::vector<char>> readTextFile(const std::string& path);
std::unique_ptr<std::vector<uint8_t>> readBinaryFile(const std::string& path);
// Read an image file into a vector byte buffer. PNG and JPG support at a
// minimum. Output format is R8G8B8A8_UINT
std::unique_ptr<std::vector<uint8_t>> ReadImageFile(const std::string& path, int& width, int& height);
std::unique_ptr<std::vector<uint8_t>> readImageFile(const std::string& path, int& width, int& height);
} // namespace engine

View File

@ -1,14 +1,12 @@
#pragma once
#include <cstdint> // uint32_t
#include <cstdint>
#include <vector>
namespace engine {
struct Vertex; // resources/mesh.h
}
namespace engine::util {
struct Vertex; // forward-dec
/*
* Generate tangents for a given list of vertices.
@ -18,6 +16,6 @@ namespace engine::util {
* Returns:
* index list for the provided vertices
*/
std::vector<uint32_t> GenTangents(std::vector<engine::Vertex>& vertices);
std::vector<uint32_t> genTangents(std::vector<engine::Vertex>& vertices);
} // namespace engine::util
} // namespace engine

View File

@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include <functional>
#include <string>
#include <type_traits>
@ -22,17 +23,17 @@ struct Image;
struct Sampler;
enum class MSAALevel {
kOff,
k2X,
k4X,
k8X,
k16X,
MSAA_OFF,
MSAA_2X,
MSAA_4X,
MSAA_8X,
MSAA_16X,
};
enum class PresentMode {
kDoubleBufferedNoVsync,
kDoubleBufferedVsync,
kTripleBuffered,
DOUBLE_BUFFERED_NO_VSYNC,
DOUBLE_BUFFERED_VSYNC,
TRIPLE_BUFFERED,
};
struct GraphicsSettings {
@ -40,8 +41,8 @@ struct GraphicsSettings {
{
// sane defaults
enable_validation = false;
present_mode = PresentMode::kDoubleBufferedVsync;
msaa_level = MSAALevel::kOff;
present_mode = PresentMode::DOUBLE_BUFFERED_VSYNC;
msaa_level = MSAALevel::MSAA_OFF;
enable_anisotropy = false; // anisotropic filtering can severely affect performance on intel iGPUs
}
@ -52,60 +53,59 @@ struct GraphicsSettings {
};
enum class ImageFormat {
kLinear,
kSRGB,
LINEAR,
SRGB,
};
enum class ShaderType {
kVertex,
kFragment,
VERTEX,
FRAGMENT,
};
enum class BufferType {
kVertex,
kIndex,
kUniform,
VERTEX,
INDEX,
UNIFORM,
};
enum class Primitive {
kPoints,
kLines,
kLineStrip,
kTriangles,
kTriangleStrip,
POINTS,
LINES,
LINE_STRIP,
TRIANGLES,
TRIANGLE_STRIP,
};
enum class CullMode { kCullNone, kCullFront, kCullBack, kCullFrontAndBack };
enum class CullMode { CULL_NONE, CULL_FRONT, CULL_BACK, CULL_FRONT_AND_BACK };
enum class VertexAttribFormat { kFloat2, kFloat3, kFloat4 };
enum class VertexAttribFormat { FLOAT2, FLOAT3, FLOAT4 };
enum class Filter : int {
kLinear,
kNearest,
LINEAR,
NEAREST,
};
enum class WrapMode : int {
kRepeat,
kMirroredRepeat,
kClampToEdge,
kClampToBorder,
REPEAT,
MIRRORED_REPEAT,
CLAMP_TO_EDGE,
CLAMP_TO_BORDER,
};
enum class DescriptorType {
kUniformBuffer,
kCombinedImageSampler,
UNIFORM_BUFFER,
COMBINED_IMAGE_SAMPLER,
};
namespace ShaderStageFlags {
enum Bits : uint32_t {
kVertex = 1 << 0,
kFragment = 1 << 1,
VERTEX = 1 << 0,
FRAGMENT = 1 << 1,
};
typedef std::underlying_type<Bits>::type Flags;
} // namespace ShaderStageFlags
struct VertexAttribDescription {
VertexAttribDescription(uint32_t location, VertexAttribFormat format, uint32_t offset) : location(location), format(format), offset(offset) {}
uint32_t location; // the index to use in the shader
VertexAttribFormat format;
uint32_t offset;
@ -129,17 +129,17 @@ struct PipelineInfo {
};
struct DescriptorSetLayoutBinding {
DescriptorType descriptor_type = DescriptorType::kUniformBuffer;
DescriptorType descriptor_type = DescriptorType::UNIFORM_BUFFER;
ShaderStageFlags::Flags stage_flags = 0;
};
struct SamplerInfo {
Filter minify = gfx::Filter::kLinear;
Filter magnify = gfx::Filter::kLinear;
Filter mipmap = gfx::Filter::kLinear;
WrapMode wrap_u = gfx::WrapMode::kRepeat;
WrapMode wrap_v = gfx::WrapMode::kRepeat;
WrapMode wrap_w = gfx::WrapMode::kRepeat; // only useful for cubemaps AFAIK
Filter minify = gfx::Filter::LINEAR;
Filter magnify = gfx::Filter::LINEAR;
Filter mipmap = gfx::Filter::LINEAR;
WrapMode wrap_u = gfx::WrapMode::REPEAT;
WrapMode wrap_v = gfx::WrapMode::REPEAT;
WrapMode wrap_w = gfx::WrapMode::REPEAT; // only useful for cubemaps AFAIK
bool anisotropic_filtering = true; // this can be force disabled by a global setting
bool operator==(const SamplerInfo&) const = default;
@ -148,6 +148,7 @@ struct SamplerInfo {
} // namespace gfx
} // namespace engine
// there has to be another way...
namespace std {
template <>
struct hash<engine::gfx::SamplerInfo> {

View File

@ -10,102 +10,71 @@ struct ImDrawData; // "imgui/imgui.h"
namespace engine {
class GFXDevice {
public:
GFXDevice(const char* app_name, const char* app_version, SDL_Window* window, gfx::GraphicsSettings settings);
GFXDevice(const GFXDevice&) = delete;
GFXDevice& operator=(const GFXDevice&) = delete;
~GFXDevice();
void GetViewportSize(uint32_t* w, uint32_t* h);
void ChangePresentMode(gfx::PresentMode mode);
gfx::PresentMode GetPresentMode();
void SetupImguiBackend();
void ShutdownImguiBackend();
void CmdRenderImguiDrawData(gfx::DrawBuffer* draw_buffer, ImDrawData* draw_data);
gfx::DrawBuffer* BeginRender(bool window_resized);
/* - draw_buffer MUST be a valid pointer returned by BeginRender().
- draw_buffer is invalid after this function has been called. */
void FinishRender(gfx::DrawBuffer* draw_buffer);
gfx::Image* CreateShadowmapImage();
gfx::DrawBuffer* BeginShadowmapRender(gfx::Image* image);
void FinishShadowmapRender(gfx::DrawBuffer* draw_buffer, gfx::Image* image);
/* - draw_buffer MUST be a valid pointer returned by BeginRender()
- pipeline MUST be a valid pointer returned by CreatePipeline() */
void CmdBindPipeline(gfx::DrawBuffer* draw_buffer, const gfx::Pipeline* pipeline);
/* - draw_buffer MUST be a valid pointer returned by BeginRender()
- buffer MUST be a valid pointer returned by CreateBuffer */
void CmdBindVertexBuffer(gfx::DrawBuffer* draw_buffer, uint32_t binding, const gfx::Buffer* buffer);
/* - draw_buffer MUST be a valid pointer returned by BeginRender()
- buffer MUST be a valid pointer returned by CreateBuffer */
void CmdBindIndexBuffer(gfx::DrawBuffer* draw_buffer, const gfx::Buffer* buffer);
void CmdDrawIndexed(gfx::DrawBuffer* draw_buffer, uint32_t index_count, uint32_t instance_count, uint32_t first_index, int32_t vertex_offset,
uint32_t first_instance);
void CmdDraw(gfx::DrawBuffer* drawBuffer, uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance);
void CmdPushConstants(gfx::DrawBuffer* draw_buffer, const gfx::Pipeline* pipeline, uint32_t offset, uint32_t size, const void* data);
void CmdBindDescriptorSet(gfx::DrawBuffer* draw_buffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t set_number);
gfx::Pipeline* CreatePipeline(const gfx::PipelineInfo& info);
void DestroyPipeline(const gfx::Pipeline* pipeline);
gfx::DescriptorSetLayout* CreateDescriptorSetLayout(const std::vector<gfx::DescriptorSetLayoutBinding>& bindings);
void DestroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout);
gfx::DescriptorSet* AllocateDescriptorSet(const gfx::DescriptorSetLayout* layout);
void FreeDescriptorSet(const gfx::DescriptorSet* set);
// This updates all copies of the descriptor.
// This cannot be used after any frames have been renderered
void UpdateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range);
void UpdateDescriptorCombinedImageSampler(const gfx::DescriptorSet* set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler);
gfx::UniformBuffer* CreateUniformBuffer(uint64_t size, const void* initial_data);
void DestroyUniformBuffer(const gfx::UniformBuffer* descriptor_buffer);
void WriteUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset, uint64_t size, const void* data);
// Loads data into staging buffer and copies that into a single GPU buffer.
gfx::Buffer* CreateBuffer(gfx::BufferType type, uint64_t size, const void* data);
void DestroyBuffer(const gfx::Buffer* buffer);
gfx::Image* CreateImage(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const void* image_data);
gfx::Image* CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const std::array<const void*, 6>& image_data);
void DestroyImage(const gfx::Image* image);
const gfx::Sampler* CreateSampler(const gfx::SamplerInfo& info);
void DestroySampler(const gfx::Sampler* sampler);
uint64_t GetFrameCount();
void LogPerformanceInfo();
// wait until all the active GPU queues have finished working
void WaitIdle();
private:
struct Impl;
std::unique_ptr<Impl> pimpl;
public:
GFXDevice(const char* app_name, const char* app_version, SDL_Window* window, gfx::GraphicsSettings settings);
GFXDevice(const GFXDevice&) = delete;
~GFXDevice();
GFXDevice& operator=(const GFXDevice&) = delete;
void getViewportSize(uint32_t* w, uint32_t* h);
void changePresentMode(gfx::PresentMode mode);
gfx::PresentMode getPresentMode();
void setupImguiBackend();
void shutdownImguiBackend();
void cmdRenderImguiDrawData(gfx::DrawBuffer* draw_buffer, ImDrawData* draw_data);
gfx::DrawBuffer* beginRender(bool window_resized);
void finishRender(gfx::DrawBuffer* draw_buffer);
gfx::DrawBuffer* beginShadowmapRender(gfx::Image* image);
void finishShadowmapRender(gfx::DrawBuffer* draw_buffer, gfx::Image* image);
void cmdBindPipeline(gfx::DrawBuffer* draw_buffer, const gfx::Pipeline* pipeline);
void cmdBindVertexBuffer(gfx::DrawBuffer* draw_buffer, uint32_t binding, const gfx::Buffer* buffer);
void cmdBindIndexBuffer(gfx::DrawBuffer* draw_buffer, const gfx::Buffer* buffer);
void cmdDrawIndexed(gfx::DrawBuffer* draw_buffer, uint32_t index_count, uint32_t instance_count, uint32_t first_index, int32_t vertex_offset,
uint32_t first_instance);
void cmdDraw(gfx::DrawBuffer* drawBuffer, uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance);
void cmdPushConstants(gfx::DrawBuffer* draw_buffer, const gfx::Pipeline* pipeline, uint32_t offset, uint32_t size, const void* data);
void cmdBindDescriptorSet(gfx::DrawBuffer* draw_buffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t set_number);
gfx::Pipeline* createPipeline(const gfx::PipelineInfo& info);
void destroyPipeline(const gfx::Pipeline* pipeline);
gfx::DescriptorSetLayout* createDescriptorSetLayout(const std::vector<gfx::DescriptorSetLayoutBinding>& bindings);
void destroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout);
gfx::DescriptorSet* allocateDescriptorSet(const gfx::DescriptorSetLayout* layout);
void freeDescriptorSet(const gfx::DescriptorSet* set);
void updateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range);
void updateDescriptorCombinedImageSampler(const gfx::DescriptorSet* set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler);
gfx::UniformBuffer* createUniformBuffer(uint64_t size, const void* initial_data);
void destroyUniformBuffer(const gfx::UniformBuffer* descriptor_buffer);
void writeUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset, uint64_t size, const void* data);
gfx::Buffer* createBuffer(gfx::BufferType type, uint64_t size, const void* data);
void destroyBuffer(const gfx::Buffer* buffer);
gfx::Image* createImage(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const void* image_data);
gfx::Image* createImageCubemap(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const std::array<const void*, 6>& image_data);
gfx::Image* createImageShadowmap();
void destroyImage(const gfx::Image* image);
const gfx::Sampler* createSampler(const gfx::SamplerInfo& info);
void destroySampler(const gfx::Sampler* sampler);
uint64_t getFrameCount();
void logPerformanceInfo();
void waitIdle();
};
} // namespace engine

View File

@ -4,17 +4,8 @@
#include "scene.h"
namespace engine::util {
namespace engine {
/*
* Loads the default scene found in a glTF file into 'scene'.
* 'isStatic' will mark every transform as static to aid rendering optimisation.
* Returns the top-level glTF node as an engine entity.
*
* Loader limitations:
* - Can only load .glb files
* - glTF files must contain all textures
*/
engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic = false);
engine::Entity loadGLTF(Scene& scene, const std::string& path, bool isStatic = false);
} // namespace engine::util
} // namespace engine

View File

@ -105,9 +105,9 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
{
const uint8_t pixel[4] = {255, 255, 255, 255};
gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.minify = gfx::Filter::NEAREST;
samplerInfo.magnify = gfx::Filter::NEAREST;
samplerInfo.mipmap = gfx::Filter::NEAREST;
samplerInfo.anisotropic_filtering = false;
auto whiteTexture = std::make_unique<Texture>(getRenderer(), pixel, 1, 1, samplerInfo, true);
getResourceManager<Texture>()->AddPersistent("builtin.white", std::move(whiteTexture));
@ -115,9 +115,9 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
{
const uint8_t pixel[4] = {0, 0, 0, 255};
gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.minify = gfx::Filter::NEAREST;
samplerInfo.magnify = gfx::Filter::NEAREST;
samplerInfo.mipmap = gfx::Filter::NEAREST;
samplerInfo.anisotropic_filtering = false;
auto blackTexture = std::make_unique<Texture>(getRenderer(), pixel, 1, 1, samplerInfo, true);
getResourceManager<Texture>()->AddPersistent("builtin.black", std::move(blackTexture));
@ -125,9 +125,9 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
{
const uint8_t pixel[4] = {127, 127, 255, 255};
gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.minify = gfx::Filter::NEAREST;
samplerInfo.magnify = gfx::Filter::NEAREST;
samplerInfo.mipmap = gfx::Filter::NEAREST;
samplerInfo.anisotropic_filtering = false;
auto normalTexture = std::make_unique<Texture>(getRenderer(), pixel, 1, 1, samplerInfo, false);
getResourceManager<Texture>()->AddPersistent("builtin.normal", std::move(normalTexture));
@ -135,9 +135,9 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
{
const uint8_t pixel[4] = {255, 127, 0, 255}; // AO, roughness, metallic
gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.minify = gfx::Filter::NEAREST;
samplerInfo.magnify = gfx::Filter::NEAREST;
samplerInfo.mipmap = gfx::Filter::NEAREST;
samplerInfo.anisotropic_filtering = false;
auto mrTexture = std::make_unique<Texture>(getRenderer(), pixel, 1, 1, samplerInfo, false);
getResourceManager<Texture>()->AddPersistent("builtin.mr", std::move(mrTexture));
@ -155,7 +155,7 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
Application::~Application()
{
m_renderer->GetDevice()->ShutdownImguiBackend();
m_renderer->GetDevice()->shutdownImguiBackend();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext(im_gui_things.context);
}
@ -177,16 +177,16 @@ void Application::gameLoop()
bool show_info_window = false;
} debug_menu_state;
debug_menu_state.enable_frame_limiter = m_configuration.enable_frame_limiter;
switch (m_renderer->GetDevice()->GetPresentMode()) {
case gfx::PresentMode::kDoubleBufferedNoVsync:
switch (m_renderer->GetDevice()->getPresentMode()) {
case gfx::PresentMode::DOUBLE_BUFFERED_NO_VSYNC:
debug_menu_state.triple_buffering = false;
debug_menu_state.vsync = false;
break;
case gfx::PresentMode::kDoubleBufferedVsync:
case gfx::PresentMode::DOUBLE_BUFFERED_VSYNC:
debug_menu_state.triple_buffering = false;
debug_menu_state.vsync = true;
break;
case gfx::PresentMode::kTripleBuffered:
case gfx::PresentMode::TRIPLE_BUFFERED:
debug_menu_state.triple_buffering = true;
debug_menu_state.vsync = false;
}
@ -207,7 +207,7 @@ void Application::gameLoop()
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
lastTick = now;
LOG_DEBUG("fps: {}", std::lroundf(avg_fps));
getRenderer()->GetDevice()->LogPerformanceInfo();
getRenderer()->GetDevice()->logPerformanceInfo();
m_window->ResetAvgFPS();
}
@ -246,10 +246,10 @@ void Application::gameLoop()
}
if (ImGui::Checkbox("Enable vsync", &debug_menu_state.vsync)) {
if (debug_menu_state.vsync) {
m_renderer->GetDevice()->ChangePresentMode(gfx::PresentMode::kDoubleBufferedVsync);
m_renderer->GetDevice()->changePresentMode(gfx::PresentMode::DOUBLE_BUFFERED_VSYNC);
}
else {
m_renderer->GetDevice()->ChangePresentMode(gfx::PresentMode::kDoubleBufferedNoVsync);
m_renderer->GetDevice()->changePresentMode(gfx::PresentMode::DOUBLE_BUFFERED_NO_VSYNC);
}
}
if (debug_menu_state.triple_buffering) {
@ -258,14 +258,14 @@ void Application::gameLoop()
if (ImGui::Checkbox("Triple buffering", &debug_menu_state.triple_buffering)) {
if (debug_menu_state.triple_buffering) {
debug_menu_state.vsync = false;
m_renderer->GetDevice()->ChangePresentMode(gfx::PresentMode::kTripleBuffered);
m_renderer->GetDevice()->changePresentMode(gfx::PresentMode::TRIPLE_BUFFERED);
}
else {
if (debug_menu_state.vsync) {
m_renderer->GetDevice()->ChangePresentMode(gfx::PresentMode::kDoubleBufferedVsync);
m_renderer->GetDevice()->changePresentMode(gfx::PresentMode::DOUBLE_BUFFERED_VSYNC);
}
else {
m_renderer->GetDevice()->ChangePresentMode(gfx::PresentMode::kDoubleBufferedNoVsync);
m_renderer->GetDevice()->changePresentMode(gfx::PresentMode::DOUBLE_BUFFERED_NO_VSYNC);
}
}
}
@ -276,9 +276,9 @@ void Application::gameLoop()
if (!scene) ImGui::BeginDisabled();
// load gltf file dialog
if (ImGui::Button("Load glTF")) {
std::filesystem::path path = util::OpenFileDialog({"glb"});
std::filesystem::path path = openFileDialog({"glb"});
if (path.empty() == false) {
util::LoadGLTF(*scene, path.string(), false);
loadGLTF(*scene, path.string(), false);
}
}
if (!scene) ImGui::EndDisabled();
@ -534,7 +534,7 @@ void Application::gameLoop()
delta_times[m_window->GetFrameCount() % delta_times.size()] = m_window->dt();
}
m_renderer->GetDevice()->WaitIdle();
m_renderer->GetDevice()->waitIdle();
}
} // namespace engine

View File

@ -11,9 +11,9 @@
#include "log.h"
namespace engine::util {
namespace engine {
std::filesystem::path OpenFileDialog(const std::vector<std::string>& extensions)
std::filesystem::path openFileDialog(const std::vector<std::string>& extensions)
{
#ifdef _WIN32
@ -55,4 +55,4 @@ std::filesystem::path OpenFileDialog(const std::vector<std::string>& extensions)
#endif
}
} // namespace engine::util
} // namespace engine

View File

@ -7,7 +7,7 @@
namespace engine {
std::unique_ptr<std::vector<char>> ReadTextFile(const std::string& path)
std::unique_ptr<std::vector<char>> readTextFile(const std::string& path)
{
std::ifstream file(path, std::ios::ate);
if (file.is_open() == false) {
@ -39,7 +39,7 @@ std::unique_ptr<std::vector<char>> ReadTextFile(const std::string& path)
return buffer;
}
std::unique_ptr<std::vector<uint8_t>> ReadBinaryFile(const std::string& path)
std::unique_ptr<std::vector<uint8_t>> readBinaryFile(const std::string& path)
{
std::ifstream file(path, std::ios::ate | std::ios::binary);
if (file.is_open() == false) {
@ -55,7 +55,7 @@ std::unique_ptr<std::vector<uint8_t>> ReadBinaryFile(const std::string& path)
return buffer;
}
std::unique_ptr<std::vector<uint8_t>> ReadImageFile(const std::string& path, int& width, int& height)
std::unique_ptr<std::vector<uint8_t>> readImageFile(const std::string& path, int& width, int& height)
{
int x, y, n;
unsigned char* data = stbi_load(path.c_str(), &x, &y, &n, STBI_rgb_alpha); // Image is 4 bpp

View File

@ -7,9 +7,9 @@
#include "resource_mesh.h"
namespace engine::util {
namespace engine {
std::vector<uint32_t> engine::util::GenTangents(std::vector<engine::Vertex>& vertices)
std::vector<uint32_t> genTangents(std::vector<engine::Vertex>& vertices)
{
using VertList = std::vector<Vertex>;
@ -64,8 +64,8 @@ std::vector<uint32_t> engine::util::GenTangents(std::vector<engine::Vertex>& ver
std::vector<uint32_t> remap_table(vertices.size()); // initialised to zeros
std::vector<Vertex> vertex_data_out(vertices.size()); // initialised to zeros
const int new_vertex_count = WeldMesh(reinterpret_cast<int*>(remap_table.data()), reinterpret_cast<float*>(vertex_data_out.data()), reinterpret_cast<float*>(vertices.data()),
static_cast<int>(vertices.size()), Vertex::floatsPerVertex());
const int new_vertex_count = WeldMesh(reinterpret_cast<int*>(remap_table.data()), reinterpret_cast<float*>(vertex_data_out.data()),
reinterpret_cast<float*>(vertices.data()), static_cast<int>(vertices.size()), Vertex::floatsPerVertex());
assert(new_vertex_count >= 0);
// get new vertices into the vector.
@ -78,4 +78,4 @@ std::vector<uint32_t> engine::util::GenTangents(std::vector<engine::Vertex>& ver
return remap_table;
}
} // namespace engine::util
} // namespace engine

View File

@ -140,11 +140,11 @@ namespace converters {
static VkFormat getVertexAttribFormat(gfx::VertexAttribFormat fmt)
{
switch (fmt) {
case gfx::VertexAttribFormat::kFloat2:
case gfx::VertexAttribFormat::FLOAT2:
return VK_FORMAT_R32G32_SFLOAT;
case gfx::VertexAttribFormat::kFloat3:
case gfx::VertexAttribFormat::FLOAT3:
return VK_FORMAT_R32G32B32_SFLOAT;
case gfx::VertexAttribFormat::kFloat4:
case gfx::VertexAttribFormat::FLOAT4:
return VK_FORMAT_R32G32B32A32_SFLOAT;
}
throw std::runtime_error("Unknown vertex attribute format");
@ -153,11 +153,11 @@ static VkFormat getVertexAttribFormat(gfx::VertexAttribFormat fmt)
static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
{
switch (type) {
case gfx::BufferType::kVertex:
case gfx::BufferType::VERTEX:
return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
case gfx::BufferType::kIndex:
case gfx::BufferType::INDEX:
return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
case gfx::BufferType::kUniform:
case gfx::BufferType::UNIFORM:
return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
default:
throw std::runtime_error("This buffer type does not have usage bits");
@ -167,9 +167,9 @@ static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
[[maybe_unused]] static VkFilter getFilter(gfx::Filter filter)
{
switch (filter) {
case gfx::Filter::kLinear:
case gfx::Filter::LINEAR:
return VK_FILTER_LINEAR;
case gfx::Filter::kNearest:
case gfx::Filter::NEAREST:
return VK_FILTER_NEAREST;
}
throw std::runtime_error("Unknown filter");
@ -178,13 +178,13 @@ static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
[[maybe_unused]] static VkSamplerAddressMode getSamplerAddressMode(gfx::WrapMode mode)
{
switch (mode) {
case gfx::WrapMode::kRepeat:
case gfx::WrapMode::REPEAT:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case gfx::WrapMode::kMirroredRepeat:
case gfx::WrapMode::MIRRORED_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case gfx::WrapMode::kClampToEdge:
case gfx::WrapMode::CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case gfx::WrapMode::kClampToBorder:
case gfx::WrapMode::CLAMP_TO_BORDER:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
}
throw std::runtime_error("Unknown wrap mode");
@ -193,9 +193,9 @@ static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
[[maybe_unused]] static VkSamplerMipmapMode getSamplerMipmapMode(gfx::Filter filter)
{
switch (filter) {
case gfx::Filter::kLinear:
case gfx::Filter::LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case gfx::Filter::kNearest:
case gfx::Filter::NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
}
throw std::runtime_error("Unknown filter");
@ -204,15 +204,15 @@ static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
[[maybe_unused]] static VkSampleCountFlagBits getSampleCountFlags(gfx::MSAALevel level)
{
switch (level) {
case gfx::MSAALevel::kOff:
case gfx::MSAALevel::MSAA_OFF:
return VK_SAMPLE_COUNT_1_BIT;
case gfx::MSAALevel::k2X:
case gfx::MSAALevel::MSAA_2X:
return VK_SAMPLE_COUNT_2_BIT;
case gfx::MSAALevel::k4X:
case gfx::MSAALevel::MSAA_4X:
return VK_SAMPLE_COUNT_4_BIT;
case gfx::MSAALevel::k8X:
case gfx::MSAALevel::MSAA_8X:
return VK_SAMPLE_COUNT_8_BIT;
case gfx::MSAALevel::k16X:
case gfx::MSAALevel::MSAA_16X:
return VK_SAMPLE_COUNT_16_BIT;
default:
throw std::runtime_error("Unknown MSAA level");
@ -222,9 +222,9 @@ static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
static VkDescriptorType getDescriptorType(gfx::DescriptorType type)
{
switch (type) {
case gfx::DescriptorType::kUniformBuffer:
case gfx::DescriptorType::UNIFORM_BUFFER:
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case gfx::DescriptorType::kCombinedImageSampler:
case gfx::DescriptorType::COMBINED_IMAGE_SAMPLER:
return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
default:
throw std::runtime_error("Unknown descriptor type");
@ -234,21 +234,21 @@ static VkDescriptorType getDescriptorType(gfx::DescriptorType type)
static VkShaderStageFlags getShaderStageFlags(gfx::ShaderStageFlags::Flags flags)
{
VkShaderStageFlags out = 0;
if (flags & gfx::ShaderStageFlags::kVertex) out |= VK_SHADER_STAGE_VERTEX_BIT;
if (flags & gfx::ShaderStageFlags::kFragment) out |= VK_SHADER_STAGE_FRAGMENT_BIT;
if (flags & gfx::ShaderStageFlags::VERTEX) out |= VK_SHADER_STAGE_VERTEX_BIT;
if (flags & gfx::ShaderStageFlags::FRAGMENT) out |= VK_SHADER_STAGE_FRAGMENT_BIT;
return out;
}
static VkCullModeFlags getCullModeFlags(gfx::CullMode mode)
{
switch (mode) {
case gfx::CullMode::kCullNone:
case gfx::CullMode::CULL_NONE:
return VK_CULL_MODE_NONE;
case gfx::CullMode::kCullFront:
case gfx::CullMode::CULL_FRONT:
return VK_CULL_MODE_FRONT_BIT;
case gfx::CullMode::kCullBack:
case gfx::CullMode::CULL_BACK:
return VK_CULL_MODE_BACK_BIT;
case gfx::CullMode::kCullFrontAndBack:
case gfx::CullMode::CULL_FRONT_AND_BACK:
return VK_CULL_MODE_FRONT_AND_BACK;
default:
throw std::runtime_error("Unknown cull mode");
@ -258,9 +258,9 @@ static VkCullModeFlags getCullModeFlags(gfx::CullMode mode)
static VkFormat getImageFormat(gfx::ImageFormat format)
{
switch (format) {
case gfx::ImageFormat::kLinear:
case gfx::ImageFormat::LINEAR:
return VK_FORMAT_R8G8B8A8_UNORM;
case gfx::ImageFormat::kSRGB:
case gfx::ImageFormat::SRGB:
return VK_FORMAT_R8G8B8A8_SRGB;
default:
throw std::runtime_error("Unknown image format");
@ -562,7 +562,7 @@ GFXDevice::~GFXDevice()
destroyVulkanInstance(pimpl->instance);
}
void GFXDevice::GetViewportSize(uint32_t* w, uint32_t* h)
void GFXDevice::getViewportSize(uint32_t* w, uint32_t* h)
{
int width, height;
SDL_Vulkan_GetDrawableSize(pimpl->window, &width, &height);
@ -576,28 +576,28 @@ void GFXDevice::GetViewportSize(uint32_t* w, uint32_t* h)
}
}
void GFXDevice::ChangePresentMode(gfx::PresentMode mode)
void GFXDevice::changePresentMode(gfx::PresentMode mode)
{
pimpl->swapchainInfo.requested_present_mode = mode;
// need to recreate swapchain to apply changes
pimpl->swapchainIsOutOfDate = true;
}
gfx::PresentMode GFXDevice::GetPresentMode()
gfx::PresentMode GFXDevice::getPresentMode()
{
switch (pimpl->swapchain.presentMode) {
case VK_PRESENT_MODE_FIFO_KHR:
return gfx::PresentMode::kDoubleBufferedVsync;
return gfx::PresentMode::DOUBLE_BUFFERED_VSYNC;
case VK_PRESENT_MODE_IMMEDIATE_KHR:
return gfx::PresentMode::kDoubleBufferedNoVsync;
return gfx::PresentMode::DOUBLE_BUFFERED_NO_VSYNC;
case VK_PRESENT_MODE_MAILBOX_KHR:
return gfx::PresentMode::kTripleBuffered;
return gfx::PresentMode::TRIPLE_BUFFERED;
default:
throw std::runtime_error("Unknown present mode");
}
}
void GFXDevice::SetupImguiBackend()
void GFXDevice::setupImguiBackend()
{
auto loaderFunc = [](const char* function_name, void* user_data) -> PFN_vkVoidFunction {
return vkGetInstanceProcAddr(*reinterpret_cast<VkInstance*>(user_data), function_name);
@ -630,18 +630,18 @@ void GFXDevice::SetupImguiBackend()
ImGui_ImplVulkan_CreateFontsTexture();
}
void GFXDevice::ShutdownImguiBackend()
void GFXDevice::shutdownImguiBackend()
{
ImGui_ImplVulkan_DestroyFontsTexture();
ImGui_ImplVulkan_Shutdown();
}
void GFXDevice::CmdRenderImguiDrawData(gfx::DrawBuffer* draw_buffer, ImDrawData* draw_data)
void GFXDevice::cmdRenderImguiDrawData(gfx::DrawBuffer* draw_buffer, ImDrawData* draw_data)
{
ImGui_ImplVulkan_RenderDrawData(draw_data, draw_buffer->frameData.drawBuf);
}
gfx::DrawBuffer* GFXDevice::BeginRender(bool window_resized)
gfx::DrawBuffer* GFXDevice::beginRender(bool window_resized)
{
VkResult res;
@ -899,7 +899,7 @@ gfx::DrawBuffer* GFXDevice::BeginRender(bool window_resized)
return drawBuffer;
}
void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
void GFXDevice::finishRender(gfx::DrawBuffer* drawBuffer)
{
assert(drawBuffer != nullptr);
@ -1009,7 +1009,7 @@ void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
delete drawBuffer;
}
gfx::Image* GFXDevice::CreateShadowmapImage()
gfx::Image* GFXDevice::createImageShadowmap()
{
if (pimpl->FRAMECOUNT != 0) abort();
@ -1054,7 +1054,7 @@ gfx::Image* GFXDevice::CreateShadowmapImage()
return out;
}
gfx::DrawBuffer* GFXDevice::BeginShadowmapRender(gfx::Image* image)
gfx::DrawBuffer* GFXDevice::beginShadowmapRender(gfx::Image* image)
{
assert(image != nullptr);
if (pimpl->FRAMECOUNT != 0) throw std::runtime_error("Can only create shadowmap before proper rendering begins.");
@ -1152,7 +1152,7 @@ gfx::DrawBuffer* GFXDevice::BeginShadowmapRender(gfx::Image* image)
return drawBuffer;
}
void GFXDevice::FinishShadowmapRender(gfx::DrawBuffer* draw_buffer, gfx::Image* image)
void GFXDevice::finishShadowmapRender(gfx::DrawBuffer* draw_buffer, gfx::Image* image)
{
assert(draw_buffer != nullptr);
@ -1211,44 +1211,44 @@ void GFXDevice::FinishShadowmapRender(gfx::DrawBuffer* draw_buffer, gfx::Image*
delete draw_buffer;
}
void GFXDevice::CmdBindPipeline(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline)
void GFXDevice::cmdBindPipeline(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline)
{
assert(drawBuffer != nullptr);
assert(pipeline != nullptr);
vkCmdBindPipeline(drawBuffer->frameData.drawBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle);
}
void GFXDevice::CmdBindVertexBuffer(gfx::DrawBuffer* drawBuffer, uint32_t binding, const gfx::Buffer* buffer)
void GFXDevice::cmdBindVertexBuffer(gfx::DrawBuffer* drawBuffer, uint32_t binding, const gfx::Buffer* buffer)
{
assert(drawBuffer != nullptr);
assert(buffer != nullptr);
assert(buffer->type == gfx::BufferType::kVertex);
assert(buffer->type == gfx::BufferType::VERTEX);
const VkDeviceSize offset = 0;
vkCmdBindVertexBuffers(drawBuffer->frameData.drawBuf, binding, 1, &buffer->buffer, &offset);
}
void GFXDevice::CmdBindIndexBuffer(gfx::DrawBuffer* drawBuffer, const gfx::Buffer* buffer)
void GFXDevice::cmdBindIndexBuffer(gfx::DrawBuffer* drawBuffer, const gfx::Buffer* buffer)
{
assert(drawBuffer != nullptr);
assert(buffer != nullptr);
assert(buffer->type == gfx::BufferType::kIndex);
assert(buffer->type == gfx::BufferType::INDEX);
vkCmdBindIndexBuffer(drawBuffer->frameData.drawBuf, buffer->buffer, 0, INDEX_TYPE);
}
void GFXDevice::CmdDrawIndexed(gfx::DrawBuffer* drawBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
void GFXDevice::cmdDrawIndexed(gfx::DrawBuffer* drawBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
uint32_t firstInstance)
{
assert(drawBuffer != nullptr);
vkCmdDrawIndexed(drawBuffer->frameData.drawBuf, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
void GFXDevice::CmdDraw(gfx::DrawBuffer* drawBuffer, uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance)
void GFXDevice::cmdDraw(gfx::DrawBuffer* drawBuffer, uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance)
{
assert(drawBuffer != nullptr);
vkCmdDraw(drawBuffer->frameData.drawBuf, vertex_count, instance_count, first_vertex, first_instance);
}
void GFXDevice::CmdPushConstants(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, uint32_t offset, uint32_t size, const void* data)
void GFXDevice::cmdPushConstants(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, uint32_t offset, uint32_t size, const void* data)
{
assert(drawBuffer != nullptr);
assert(pipeline != nullptr);
@ -1256,7 +1256,7 @@ void GFXDevice::CmdPushConstants(gfx::DrawBuffer* drawBuffer, const gfx::Pipelin
vkCmdPushConstants(drawBuffer->frameData.drawBuf, pipeline->layout, VK_SHADER_STAGE_VERTEX_BIT, offset, size, data);
}
void GFXDevice::CmdBindDescriptorSet(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t setNumber)
void GFXDevice::cmdBindDescriptorSet(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t setNumber)
{
assert(drawBuffer != nullptr);
assert(pipeline != nullptr);
@ -1265,7 +1265,7 @@ void GFXDevice::CmdBindDescriptorSet(gfx::DrawBuffer* drawBuffer, const gfx::Pip
&set->sets[drawBuffer->currentFrameIndex], 0, nullptr);
}
gfx::Pipeline* GFXDevice::CreatePipeline(const gfx::PipelineInfo& info)
gfx::Pipeline* GFXDevice::createPipeline(const gfx::PipelineInfo& info)
{
[[maybe_unused]] VkResult res;
@ -1273,13 +1273,13 @@ gfx::Pipeline* GFXDevice::CreatePipeline(const gfx::PipelineInfo& info)
VkShaderModule vertShaderModule;
VkShaderModule fragShaderModule;
// be careful with these .c_str() calls. It is OK here because 'info' exists for the duration of CreatePipeline()
// be careful with these .c_str() calls. It is OK here because 'info' exists for the duration of createPipeline()
{
auto vertShaderCode = ReadTextFile(info.vert_shader_path.c_str());
auto vertShaderCode = readTextFile(info.vert_shader_path.c_str());
vertShaderModule = compileShader(pimpl->device.device, shaderc_vertex_shader, vertShaderCode->data(), info.vert_shader_path.c_str());
}
{
auto fragShaderCode = ReadTextFile(info.frag_shader_path.c_str());
auto fragShaderCode = readTextFile(info.frag_shader_path.c_str());
fragShaderModule = compileShader(pimpl->device.device, shaderc_fragment_shader, fragShaderCode->data(), info.frag_shader_path.c_str());
}
@ -1497,7 +1497,7 @@ gfx::Pipeline* GFXDevice::CreatePipeline(const gfx::PipelineInfo& info)
return pipeline;
}
void GFXDevice::DestroyPipeline(const gfx::Pipeline* pipeline)
void GFXDevice::destroyPipeline(const gfx::Pipeline* pipeline)
{
assert(pipeline != nullptr);
vkDestroyPipeline(pimpl->device.device, pipeline->handle, nullptr);
@ -1505,7 +1505,7 @@ void GFXDevice::DestroyPipeline(const gfx::Pipeline* pipeline)
delete pipeline;
}
gfx::DescriptorSetLayout* GFXDevice::CreateDescriptorSetLayout(const std::vector<gfx::DescriptorSetLayoutBinding>& bindings)
gfx::DescriptorSetLayout* GFXDevice::createDescriptorSetLayout(const std::vector<gfx::DescriptorSetLayoutBinding>& bindings)
{
gfx::DescriptorSetLayout* out = new gfx::DescriptorSetLayout{};
@ -1532,13 +1532,13 @@ gfx::DescriptorSetLayout* GFXDevice::CreateDescriptorSetLayout(const std::vector
return out;
}
void GFXDevice::DestroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout)
void GFXDevice::destroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout)
{
vkDestroyDescriptorSetLayout(pimpl->device.device, layout->layout, nullptr);
delete layout;
}
gfx::DescriptorSet* GFXDevice::AllocateDescriptorSet(const gfx::DescriptorSetLayout* layout)
gfx::DescriptorSet* GFXDevice::allocateDescriptorSet(const gfx::DescriptorSetLayout* layout)
{
assert(layout != nullptr);
@ -1560,13 +1560,13 @@ gfx::DescriptorSet* GFXDevice::AllocateDescriptorSet(const gfx::DescriptorSetLay
return set;
}
void GFXDevice::FreeDescriptorSet(const gfx::DescriptorSet* set)
void GFXDevice::freeDescriptorSet(const gfx::DescriptorSet* set)
{
assert(set != nullptr);
VKCHECK(vkFreeDescriptorSets(pimpl->device.device, pimpl->descriptorPool, static_cast<uint32_t>(set->sets.size()), set->sets.data()));
}
void GFXDevice::UpdateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range)
void GFXDevice::updateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range)
{
assert(set != nullptr);
assert(buffer != nullptr);
@ -1589,7 +1589,7 @@ void GFXDevice::UpdateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uin
}
}
void GFXDevice::UpdateDescriptorCombinedImageSampler(const gfx::DescriptorSet* set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler)
void GFXDevice::updateDescriptorCombinedImageSampler(const gfx::DescriptorSet* set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler)
{
assert(set != nullptr);
assert(image != nullptr);
@ -1617,7 +1617,7 @@ void GFXDevice::UpdateDescriptorCombinedImageSampler(const gfx::DescriptorSet* s
}
}
gfx::UniformBuffer* GFXDevice::CreateUniformBuffer(uint64_t size, const void* initialData)
gfx::UniformBuffer* GFXDevice::createUniformBuffer(uint64_t size, const void* initialData)
{
assert(initialData != nullptr);
@ -1627,7 +1627,7 @@ gfx::UniformBuffer* GFXDevice::CreateUniformBuffer(uint64_t size, const void* in
/* first make staging buffer */
out->stagingBuffer.size = size;
out->stagingBuffer.type = gfx::BufferType::kUniform;
out->stagingBuffer.type = gfx::BufferType::UNIFORM;
{
VkBufferCreateInfo stagingBufferInfo{};
stagingBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -1653,7 +1653,7 @@ gfx::UniformBuffer* GFXDevice::CreateUniformBuffer(uint64_t size, const void* in
/* create the device-local set of buffers */
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
out->gpuBuffers[i].size = out->stagingBuffer.size;
out->gpuBuffers[i].type = gfx::BufferType::kUniform;
out->gpuBuffers[i].type = gfx::BufferType::UNIFORM;
VkBufferCreateInfo gpuBufferInfo{};
gpuBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -1677,7 +1677,7 @@ gfx::UniformBuffer* GFXDevice::CreateUniformBuffer(uint64_t size, const void* in
return out;
}
void GFXDevice::DestroyUniformBuffer(const gfx::UniformBuffer* uniformBuffer)
void GFXDevice::destroyUniformBuffer(const gfx::UniformBuffer* uniformBuffer)
{
assert(uniformBuffer != nullptr);
@ -1690,7 +1690,7 @@ void GFXDevice::DestroyUniformBuffer(const gfx::UniformBuffer* uniformBuffer)
delete uniformBuffer;
}
void GFXDevice::WriteUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset, uint64_t size, const void* data)
void GFXDevice::writeUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset, uint64_t size, const void* data)
{
assert(buffer != nullptr);
assert(data != nullptr);
@ -1710,7 +1710,7 @@ void GFXDevice::WriteUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset,
}
}
gfx::Buffer* GFXDevice::CreateBuffer(gfx::BufferType type, uint64_t size, const void* data)
gfx::Buffer* GFXDevice::createBuffer(gfx::BufferType type, uint64_t size, const void* data)
{
assert(data != nullptr);
@ -1769,7 +1769,7 @@ gfx::Buffer* GFXDevice::CreateBuffer(gfx::BufferType type, uint64_t size, const
return out;
}
void GFXDevice::DestroyBuffer(const gfx::Buffer* buffer)
void GFXDevice::destroyBuffer(const gfx::Buffer* buffer)
{
assert(buffer != nullptr);
vmaDestroyBuffer(pimpl->allocator, buffer->buffer, buffer->allocation);
@ -1777,7 +1777,7 @@ void GFXDevice::DestroyBuffer(const gfx::Buffer* buffer)
}
// imageData must have pixel format R8G8B8A8
gfx::Image* GFXDevice::CreateImage(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const void* imageData)
gfx::Image* GFXDevice::createImage(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const void* imageData)
{
assert(imageData != nullptr);
@ -2032,7 +2032,7 @@ gfx::Image* GFXDevice::CreateImage(uint32_t w, uint32_t h, gfx::ImageFormat inpu
return out;
}
gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const std::array<const void*, 6>& image_data)
gfx::Image* GFXDevice::createImageCubemap(uint32_t w, uint32_t h, gfx::ImageFormat input_format, const std::array<const void*, 6>& image_data)
{
assert(image_data[0] != nullptr);
assert(image_data[1] != nullptr);
@ -2291,7 +2291,7 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
return out;
}
void GFXDevice::DestroyImage(const gfx::Image* image)
void GFXDevice::destroyImage(const gfx::Image* image)
{
assert(image != nullptr);
vkDestroyImageView(pimpl->device.device, image->view, nullptr);
@ -2299,7 +2299,7 @@ void GFXDevice::DestroyImage(const gfx::Image* image)
delete image;
}
const gfx::Sampler* GFXDevice::CreateSampler(const gfx::SamplerInfo& info)
const gfx::Sampler* GFXDevice::createSampler(const gfx::SamplerInfo& info)
{
gfx::Sampler* out = new gfx::Sampler{};
@ -2323,14 +2323,14 @@ const gfx::Sampler* GFXDevice::CreateSampler(const gfx::SamplerInfo& info)
return out;
}
void GFXDevice::DestroySampler(const gfx::Sampler* sampler)
void GFXDevice::destroySampler(const gfx::Sampler* sampler)
{
assert(sampler != nullptr);
vkDestroySampler(pimpl->device.device, sampler->sampler, nullptr);
delete sampler;
}
void GFXDevice::LogPerformanceInfo()
void GFXDevice::logPerformanceInfo()
{
VmaTotalStatistics pStats{};
vmaCalculateStatistics(pimpl->allocator, &pStats);
@ -2354,8 +2354,9 @@ void GFXDevice::LogPerformanceInfo()
}
}
uint64_t GFXDevice::GetFrameCount() { return pimpl->FRAMECOUNT; }
uint64_t GFXDevice::getFrameCount() { return pimpl->FRAMECOUNT; }
void GFXDevice::WaitIdle() { vkDeviceWaitIdle(pimpl->device.device); }
/* Waits until all the active GPU queues have finished working */
void GFXDevice::waitIdle() { vkDeviceWaitIdle(pimpl->device.device); }
} // namespace engine

View File

@ -38,7 +38,7 @@ struct std::hash<Color> {
namespace tg = tinygltf;
namespace engine::util {
namespace engine {
template <typename T>
struct Attribute {
@ -88,7 +88,17 @@ static glm::mat4 MatFromDoubleArray(const std::vector<double>& arr)
return mat;
}
engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
/*
* Loads the default scene found in a glTF file into 'scene'.
* 'isStatic' will mark every transform as static to aid rendering optimisation.
* Returns the top-level glTF node as an engine entity.
*
* Loader limitations:
* - Can only load .glb files
* - glTF files must contain all textures
* - No extension support
*/
engine::Entity loadGLTF(Scene& scene, const std::string& path, bool isStatic)
{
LOG_INFO("Loading gltf file: {}", path);
@ -161,46 +171,46 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
gfx::SamplerInfo samplerInfo{};
// default to trilinear filtering even if mipmaps are not specified
samplerInfo.minify = gfx::Filter::kLinear;
samplerInfo.magnify = gfx::Filter::kLinear;
samplerInfo.mipmap = gfx::Filter::kLinear;
samplerInfo.minify = gfx::Filter::LINEAR;
samplerInfo.magnify = gfx::Filter::LINEAR;
samplerInfo.mipmap = gfx::Filter::LINEAR;
if (texture.sampler != -1) {
const tg::Sampler& sampler = model.samplers.at(texture.sampler);
switch (sampler.minFilter) {
case TINYGLTF_TEXTURE_FILTER_NEAREST:
case TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR:
samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::kLinear;
samplerInfo.minify = gfx::Filter::NEAREST;
samplerInfo.mipmap = gfx::Filter::LINEAR;
break;
case TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST:
samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.minify = gfx::Filter::NEAREST;
samplerInfo.mipmap = gfx::Filter::NEAREST;
break;
case TINYGLTF_TEXTURE_FILTER_LINEAR:
case TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR:
samplerInfo.minify = gfx::Filter::kLinear;
samplerInfo.mipmap = gfx::Filter::kLinear;
samplerInfo.minify = gfx::Filter::LINEAR;
samplerInfo.mipmap = gfx::Filter::LINEAR;
break;
case TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST:
samplerInfo.minify = gfx::Filter::kLinear;
samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.minify = gfx::Filter::LINEAR;
samplerInfo.mipmap = gfx::Filter::NEAREST;
break;
default:
break;
}
switch (sampler.magFilter) {
case TINYGLTF_TEXTURE_FILTER_NEAREST:
samplerInfo.magnify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::NEAREST;
break;
case TINYGLTF_TEXTURE_FILTER_LINEAR:
samplerInfo.magnify = gfx::Filter::kLinear;
samplerInfo.magnify = gfx::Filter::LINEAR;
break;
default:
break;
}
}
// use aniso if min filter is LINEAR_MIPMAP_LINEAR
samplerInfo.anisotropic_filtering = (samplerInfo.minify == gfx::Filter::kLinear && samplerInfo.mipmap == gfx::Filter::kLinear);
samplerInfo.anisotropic_filtering = (samplerInfo.minify == gfx::Filter::LINEAR && samplerInfo.mipmap == gfx::Filter::LINEAR);
const tg::Image& image = model.images.at(texture.source);
if (image.as_is == false && image.bits == 8 && image.component == 4 && image.pixel_type == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
@ -265,9 +275,9 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
if (colour_textures.contains(c) == false) {
const uint8_t pixel[4] = {c.r, c.g, c.b, c.a};
gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.minify = gfx::Filter::NEAREST;
samplerInfo.magnify = gfx::Filter::NEAREST;
samplerInfo.mipmap = gfx::Filter::NEAREST;
samplerInfo.anisotropic_filtering = false;
colour_textures.emplace(std::make_pair(c, std::make_shared<Texture>(scene.app()->getRenderer(), pixel, 1, 1, samplerInfo, true)));
}
@ -294,9 +304,9 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
if (metal_rough_textures.contains(mr) == false) {
const uint8_t pixel[4] = {mr.r, mr.g, mr.b, mr.a};
gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.minify = gfx::Filter::NEAREST;
samplerInfo.magnify = gfx::Filter::NEAREST;
samplerInfo.mipmap = gfx::Filter::NEAREST;
samplerInfo.anisotropic_filtering = false;
metal_rough_textures.emplace(std::make_pair(mr, std::make_shared<Texture>(scene.app()->getRenderer(), pixel, 1, 1, samplerInfo, false)));
}
@ -672,4 +682,4 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
return parent;
}
} // namespace engine::util
} // namespace engine

View File

@ -22,17 +22,17 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
std::vector<gfx::DescriptorSetLayoutBinding> globalSetBindings;
{
auto& binding0 = globalSetBindings.emplace_back();
binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
binding0.descriptor_type = gfx::DescriptorType::UNIFORM_BUFFER;
binding0.stage_flags = gfx::ShaderStageFlags::VERTEX;
auto& binding1 = globalSetBindings.emplace_back();
binding1.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
binding1.stage_flags = gfx::ShaderStageFlags::kFragment;
binding1.descriptor_type = gfx::DescriptorType::COMBINED_IMAGE_SAMPLER;
binding1.stage_flags = gfx::ShaderStageFlags::FRAGMENT;
auto& binding2 = globalSetBindings.emplace_back();
binding2.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
binding2.stage_flags = gfx::ShaderStageFlags::kFragment;
binding2.descriptor_type = gfx::DescriptorType::COMBINED_IMAGE_SAMPLER;
binding2.stage_flags = gfx::ShaderStageFlags::FRAGMENT;
}
global_uniform.layout = device_->CreateDescriptorSetLayout(globalSetBindings);
global_uniform.set = device_->AllocateDescriptorSet(global_uniform.layout);
global_uniform.layout = device_->createDescriptorSetLayout(globalSetBindings);
global_uniform.set = device_->allocateDescriptorSet(global_uniform.layout);
const glm::vec3 light_location = glm::vec3{-0.4278, 0.7923, 0.43502} * 40.0f;
// const glm::vec3 light_location = glm::vec3{10.0f, 0.0f, 10.0f};
const glm::mat4 light_proj = glm::orthoRH_ZO(-24.0f, 24.0f, -15.0f, 15.0f, 10.0f, 65.0f);
@ -40,34 +40,34 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
const glm::mat4 light_view = glm::lookAtRH(light_location, glm::vec3{0.0f, 0.0f, 0.0f}, glm::vec3{0.0f, 0.0f, 1.0f});
global_uniform.uniform_buffer_data.data.proj = light_proj;
global_uniform.uniform_buffer_data.data.lightSpaceMatrix = light_proj * light_view;
global_uniform.uniform_buffer = device_->CreateUniformBuffer(sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
device_->UpdateDescriptorUniformBuffer(global_uniform.set, 0, global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data));
global_uniform.uniform_buffer = device_->createUniformBuffer(sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
device_->updateDescriptorUniformBuffer(global_uniform.set, 0, global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data));
// binding1 is updated towards the end of the constructor once the skybox texture is loaded
// binding2 is updated just after that
std::vector<gfx::DescriptorSetLayoutBinding> frameSetBindings;
{
auto& binding0 = frameSetBindings.emplace_back();
binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
binding0.descriptor_type = gfx::DescriptorType::UNIFORM_BUFFER;
binding0.stage_flags = gfx::ShaderStageFlags::VERTEX;
}
frame_uniform.layout = device_->CreateDescriptorSetLayout(frameSetBindings);
frame_uniform.set = device_->AllocateDescriptorSet(frame_uniform.layout);
frame_uniform.layout = device_->createDescriptorSetLayout(frameSetBindings);
frame_uniform.set = device_->allocateDescriptorSet(frame_uniform.layout);
frame_uniform.uniform_buffer_data.data = light_view;
frame_uniform.uniform_buffer = device_->CreateUniformBuffer(sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
device_->UpdateDescriptorUniformBuffer(frame_uniform.set, 0, frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data));
frame_uniform.uniform_buffer = device_->createUniformBuffer(sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
device_->updateDescriptorUniformBuffer(frame_uniform.set, 0, frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data));
std::vector<gfx::DescriptorSetLayoutBinding> materialSetBindings;
gfx::DescriptorSetLayoutBinding materialSetBinding{};
materialSetBinding.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
materialSetBinding.stage_flags = gfx::ShaderStageFlags::kFragment;
materialSetBinding.descriptor_type = gfx::DescriptorType::COMBINED_IMAGE_SAMPLER;
materialSetBinding.stage_flags = gfx::ShaderStageFlags::FRAGMENT;
materialSetBindings.push_back(materialSetBinding); // albedo
materialSetBindings.push_back(materialSetBinding); // normal
materialSetBindings.push_back(materialSetBinding); // occlusion
materialSetBindings.push_back(materialSetBinding); // metallic-roughness
material_set_layout = device_->CreateDescriptorSetLayout(materialSetBindings);
material_set_layout = device_->createDescriptorSetLayout(materialSetBindings);
device_->SetupImguiBackend();
device_->setupImguiBackend();
gfx::VertexFormat debug_vertex_format{};
debug_vertex_format.stride = 0;
@ -79,12 +79,12 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
debug_pipeline_info.frag_shader_path = getResourcePath("engine/shaders/debug.frag");
debug_pipeline_info.vertex_format = debug_vertex_format;
debug_pipeline_info.alpha_blending = false;
debug_pipeline_info.face_cull_mode = gfx::CullMode::kCullNone; // probably ignored for line rendering
debug_pipeline_info.face_cull_mode = gfx::CullMode::CULL_NONE; // probably ignored for line rendering
debug_pipeline_info.write_z = false; // lines don't need the depth buffer
// debug_pipeline_info.descriptor_set_layouts = empty;
debug_pipeline_info.line_primitives = true;
debug_rendering_things_.pipeline = device_->CreatePipeline(debug_pipeline_info);
debug_rendering_things_.pipeline = device_->createPipeline(debug_pipeline_info);
}
// create the skybox cubemap and update global skybox combined-image-sampler
@ -97,29 +97,29 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
for (int face = 0; face < 6; ++face) {
std::string path = std::string("engine/textures/skybox") + std::to_string(face) + std::string(".jpg");
face_unq_ptrs[face] = ReadImageFile(getResourcePath(path), w, h);
face_unq_ptrs[face] = readImageFile(getResourcePath(path), w, h);
if (cubemap_w != w || cubemap_h != h) throw std::runtime_error("Skybox textures must be 512x512!");
face_unsafe_ptrs[face] = face_unq_ptrs[face]->data();
}
skybox_cubemap = device_->CreateImageCubemap(cubemap_w, cubemap_h, gfx::ImageFormat::kSRGB, face_unsafe_ptrs);
skybox_cubemap = device_->createImageCubemap(cubemap_w, cubemap_h, gfx::ImageFormat::SRGB, face_unsafe_ptrs);
gfx::SamplerInfo sampler_info{};
sampler_info.magnify = gfx::Filter::kLinear;
sampler_info.minify = gfx::Filter::kLinear;
sampler_info.mipmap = gfx::Filter::kLinear;
sampler_info.wrap_u = gfx::WrapMode::kClampToEdge;
sampler_info.wrap_v = gfx::WrapMode::kClampToEdge;
sampler_info.wrap_w = gfx::WrapMode::kClampToEdge;
sampler_info.magnify = gfx::Filter::LINEAR;
sampler_info.minify = gfx::Filter::LINEAR;
sampler_info.mipmap = gfx::Filter::LINEAR;
sampler_info.wrap_u = gfx::WrapMode::CLAMP_TO_EDGE;
sampler_info.wrap_v = gfx::WrapMode::CLAMP_TO_EDGE;
sampler_info.wrap_w = gfx::WrapMode::CLAMP_TO_EDGE;
sampler_info.anisotropic_filtering = true;
skybox_sampler = device_->CreateSampler(sampler_info);
skybox_sampler = device_->createSampler(sampler_info);
device_->UpdateDescriptorCombinedImageSampler(global_uniform.set, 1, skybox_cubemap, skybox_sampler);
device_->updateDescriptorCombinedImageSampler(global_uniform.set, 1, skybox_cubemap, skybox_sampler);
}
// create skybox shader
{
gfx::VertexFormat vertex_format{};
vertex_format.attribute_descriptions.emplace_back(0u, gfx::VertexAttribFormat::kFloat3, 0u);
vertex_format.attribute_descriptions.emplace_back(0u, gfx::VertexAttribFormat::FLOAT3, 0u);
vertex_format.stride = 3 * sizeof(float);
gfx::PipelineInfo pipeline_info{};
@ -127,13 +127,13 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
pipeline_info.frag_shader_path = getResourcePath("engine/shaders/skybox.frag");
pipeline_info.vertex_format = vertex_format;
pipeline_info.alpha_blending = false;
pipeline_info.face_cull_mode = gfx::CullMode::kCullBack;
pipeline_info.face_cull_mode = gfx::CullMode::CULL_BACK;
pipeline_info.write_z = false;
pipeline_info.line_primitives = false;
pipeline_info.descriptor_set_layouts.push_back(GetGlobalSetLayout());
pipeline_info.descriptor_set_layouts.push_back(GetFrameSetLayout());
skybox_pipeline = device_->CreatePipeline(pipeline_info);
skybox_pipeline = device_->createPipeline(pipeline_info);
}
// create skybox vertex buffer
@ -189,19 +189,19 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
std::swap(v[i], v[i + 2]);
}
skybox_buffer = device_->CreateBuffer(gfx::BufferType::kVertex, v.size() * sizeof(glm::vec3), v.data());
skybox_buffer = device_->createBuffer(gfx::BufferType::VERTEX, v.size() * sizeof(glm::vec3), v.data());
}
// shadow map pipeline
gfx::VertexFormat shadowVertexFormat{};
shadowVertexFormat.stride = sizeof(float) * 12; // using the full meshes so a lot of data is skipped
shadowVertexFormat.attribute_descriptions.emplace_back(0u, gfx::VertexAttribFormat::kFloat3, 0u); // position
shadowVertexFormat.attribute_descriptions.emplace_back(1u, gfx::VertexAttribFormat::kFloat2, static_cast<uint32_t>(sizeof(float)) * 10u); // uv
shadowVertexFormat.attribute_descriptions.emplace_back(0u, gfx::VertexAttribFormat::FLOAT3, 0u); // position
shadowVertexFormat.attribute_descriptions.emplace_back(1u, gfx::VertexAttribFormat::FLOAT2, static_cast<uint32_t>(sizeof(float)) * 10u); // uv
gfx::PipelineInfo shadowPipelineInfo{};
shadowPipelineInfo.vert_shader_path = getResourcePath("engine/shaders/shadow.vert");
shadowPipelineInfo.frag_shader_path = getResourcePath("engine/shaders/shadow.frag");
shadowPipelineInfo.vertex_format = shadowVertexFormat;
shadowPipelineInfo.face_cull_mode = gfx::CullMode::kCullFront; // shadows care about back faces
shadowPipelineInfo.face_cull_mode = gfx::CullMode::CULL_FRONT; // shadows care about back faces
shadowPipelineInfo.alpha_blending = false;
shadowPipelineInfo.write_z = true;
shadowPipelineInfo.line_primitives = false;
@ -209,140 +209,142 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
shadowPipelineInfo.descriptor_set_layouts.emplace_back(GetGlobalSetLayout());
shadowPipelineInfo.descriptor_set_layouts.emplace_back(GetFrameSetLayout());
shadowPipelineInfo.descriptor_set_layouts.emplace_back(GetMaterialSetLayout());
shadow_pipeline = device_->CreatePipeline(shadowPipelineInfo);
shadow_pipeline = device_->createPipeline(shadowPipelineInfo);
// shadow map image and sampler
shadow_map = device_->CreateShadowmapImage();
shadow_map = device_->createImageShadowmap();
gfx::SamplerInfo sampler_info{};
sampler_info.magnify = gfx::Filter::kLinear;
sampler_info.minify = gfx::Filter::kLinear;
sampler_info.mipmap = gfx::Filter::kNearest; // bilinear is apparently good for shadow maps, mips aren't used anyway
sampler_info.wrap_u = gfx::WrapMode::kClampToBorder; // sampler reads 1.0 out of bounds which ensures no shadowing there
sampler_info.wrap_v = gfx::WrapMode::kClampToBorder;
sampler_info.wrap_w = gfx::WrapMode::kClampToBorder;
sampler_info.magnify = gfx::Filter::LINEAR;
sampler_info.minify = gfx::Filter::LINEAR;
sampler_info.mipmap = gfx::Filter::NEAREST; // bilinear is apparently good for shadow maps, mips aren't used anyway
sampler_info.wrap_u = gfx::WrapMode::CLAMP_TO_BORDER; // sampler reads 1.0 out of bounds which ensures no shadowing there
sampler_info.wrap_v = gfx::WrapMode::CLAMP_TO_BORDER;
sampler_info.wrap_w = gfx::WrapMode::CLAMP_TO_BORDER;
sampler_info.anisotropic_filtering = false; // no mip-maps so aniso won't do anything
shadow_map_sampler = device_->CreateSampler(sampler_info);
device_->UpdateDescriptorCombinedImageSampler(global_uniform.set, 2, shadow_map, shadow_map_sampler);
shadow_map_sampler = device_->createSampler(sampler_info);
device_->updateDescriptorCombinedImageSampler(global_uniform.set, 2, shadow_map, shadow_map_sampler);
};
Renderer::~Renderer()
{
device_->DestroySampler(shadow_map_sampler);
device_->DestroyImage(shadow_map);
device_->DestroyPipeline(shadow_pipeline);
device_->destroySampler(shadow_map_sampler);
device_->destroyImage(shadow_map);
device_->destroyPipeline(shadow_pipeline);
device_->DestroyBuffer(skybox_buffer);
device_->DestroyPipeline(skybox_pipeline);
device_->DestroySampler(skybox_sampler);
device_->DestroyImage(skybox_cubemap);
device_->destroyBuffer(skybox_buffer);
device_->destroyPipeline(skybox_pipeline);
device_->destroySampler(skybox_sampler);
device_->destroyImage(skybox_cubemap);
device_->DestroyPipeline(debug_rendering_things_.pipeline);
device_->destroyPipeline(debug_rendering_things_.pipeline);
for (const auto& [info, sampler] : samplers) {
device_->DestroySampler(sampler);
device_->destroySampler(sampler);
}
device_->DestroyDescriptorSetLayout(material_set_layout);
device_->destroyDescriptorSetLayout(material_set_layout);
device_->DestroyUniformBuffer(frame_uniform.uniform_buffer);
device_->DestroyDescriptorSetLayout(frame_uniform.layout);
device_->destroyUniformBuffer(frame_uniform.uniform_buffer);
device_->destroyDescriptorSetLayout(frame_uniform.layout);
device_->DestroyUniformBuffer(global_uniform.uniform_buffer);
device_->DestroyDescriptorSetLayout(global_uniform.layout);
device_->destroyUniformBuffer(global_uniform.uniform_buffer);
device_->destroyDescriptorSetLayout(global_uniform.layout);
}
void Renderer::Render(bool window_is_resized, glm::mat4 camera_transform, const RenderList* static_list, const RenderList* dynamic_list, const std::vector<DebugLine>& debug_lines)
void Renderer::Render(bool window_is_resized, glm::mat4 camera_transform, const RenderList* static_list, const RenderList* dynamic_list,
const std::vector<DebugLine>& debug_lines)
{
if (window_is_resized) {
uint32_t w, h;
device_->GetViewportSize(&w, &h);
device_->getViewportSize(&w, &h);
viewport_aspect_ratio_ = (float)w / (float)h;
const glm::mat4 proj_matrix =
glm::perspectiveRH_ZO(camera_settings_.vertical_fov_radians, viewport_aspect_ratio_, camera_settings_.clip_near, camera_settings_.clip_far);
/* update SET 0 (rarely changing uniforms)*/
global_uniform.uniform_buffer_data.data.proj = proj_matrix;
device_->WriteUniformBuffer(global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
device_->writeUniformBuffer(global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
}
const glm::mat4 view_matrix = glm::inverse(camera_transform);
frame_uniform.uniform_buffer_data.data = view_matrix;
device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
device_->writeUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
if (rendering_started == false) {
// render to shadow map
gfx::DrawBuffer* shadow_draw = device_->BeginShadowmapRender(shadow_map);
device_->CmdBindPipeline(shadow_draw, shadow_pipeline);
device_->CmdBindDescriptorSet(shadow_draw, shadow_pipeline, global_uniform.set, 0); // only need light space matrix
gfx::DrawBuffer* shadow_draw = device_->beginShadowmapRender(shadow_map);
device_->cmdBindPipeline(shadow_draw, shadow_pipeline);
device_->cmdBindDescriptorSet(shadow_draw, shadow_pipeline, global_uniform.set, 0); // only need light space matrix
if (static_list) { // only create shadow map with static meshes
if (!static_list->empty()) {
for (const auto& entry : *static_list) {
device_->CmdPushConstants(shadow_draw, shadow_pipeline, 0, sizeof(entry.model_matrix), &entry.model_matrix);
device_->CmdBindDescriptorSet(shadow_draw, shadow_pipeline, entry.material_set, 2);
device_->CmdBindVertexBuffer(shadow_draw, 0, entry.vertex_buffer);
device_->CmdBindIndexBuffer(shadow_draw, entry.index_buffer);
device_->CmdDrawIndexed(shadow_draw, entry.index_count, 1, 0, 0, 0);
device_->cmdPushConstants(shadow_draw, shadow_pipeline, 0, sizeof(entry.model_matrix), &entry.model_matrix);
device_->cmdBindDescriptorSet(shadow_draw, shadow_pipeline, entry.material_set, 2); // need to sample base color texture for alpha clipping
device_->cmdBindVertexBuffer(shadow_draw, 0, entry.vertex_buffer);
device_->cmdBindIndexBuffer(shadow_draw, entry.index_buffer);
device_->cmdDrawIndexed(shadow_draw, entry.index_count, 1, 0, 0, 0);
}
}
}
device_->FinishShadowmapRender(shadow_draw, shadow_map);
device_->finishShadowmapRender(shadow_draw, shadow_map);
}
rendering_started = true;
last_bound_pipeline_ = nullptr;
gfx::DrawBuffer* draw_buffer = device_->BeginRender(window_is_resized);
gfx::DrawBuffer* draw_buffer = device_->beginRender(window_is_resized);
// Draw static objects
if (static_list) {
if (!static_list->empty()) {
DrawRenderList(draw_buffer, *static_list);
}
}
// Draw moving objects
if (dynamic_list) {
if (!dynamic_list->empty()) {
DrawRenderList(draw_buffer, *dynamic_list);
}
}
// draw skybox
{
device_->cmdBindPipeline(draw_buffer, skybox_pipeline);
device_->cmdBindDescriptorSet(draw_buffer, skybox_pipeline, global_uniform.set, 0);
device_->cmdBindDescriptorSet(draw_buffer, skybox_pipeline, frame_uniform.set, 1);
device_->cmdBindVertexBuffer(draw_buffer, 0, skybox_buffer);
device_->cmdDraw(draw_buffer, 36, 1, 0, 0);
}
struct DebugPush {
glm::vec4 pos1;
glm::vec4 pos2;
glm::vec3 color;
};
// draw skybox
{
device_->CmdBindPipeline(draw_buffer, skybox_pipeline);
device_->CmdBindDescriptorSet(draw_buffer, skybox_pipeline, global_uniform.set, 0);
device_->CmdBindDescriptorSet(draw_buffer, skybox_pipeline, frame_uniform.set, 1);
device_->CmdBindVertexBuffer(draw_buffer, 0, skybox_buffer);
device_->CmdDraw(draw_buffer, 36, 1, 0, 0);
}
// draw debug shit here
device_->CmdBindPipeline(draw_buffer, debug_rendering_things_.pipeline);
device_->cmdBindPipeline(draw_buffer, debug_rendering_things_.pipeline);
DebugPush push{};
for (const DebugLine& l : debug_lines) {
push.pos1 = global_uniform.uniform_buffer_data.data.proj * frame_uniform.uniform_buffer_data.data * glm::vec4(l.pos1, 1.0f);
push.pos2 = global_uniform.uniform_buffer_data.data.proj * frame_uniform.uniform_buffer_data.data * glm::vec4(l.pos2, 1.0f);
push.color = l.color;
device_->CmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(DebugPush), &push);
device_->CmdDraw(draw_buffer, 2, 1, 0, 0);
device_->cmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(DebugPush), &push);
device_->cmdDraw(draw_buffer, 2, 1, 0, 0);
}
// also make a lil crosshair
push.color = glm::vec3{1.0f, 1.0f, 1.0f};
push.pos1 = glm::vec4(-0.05f, 0.0f, 0.0f, 1.0f);
push.pos2 = glm::vec4(0.05f, 0.0f, 0.0f, 1.0f);
device_->CmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(DebugPush), &push);
device_->CmdDraw(draw_buffer, 2, 1, 0, 0);
device_->cmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(DebugPush), &push);
device_->cmdDraw(draw_buffer, 2, 1, 0, 0);
push.pos1 = glm::vec4(0.0f, -0.05f, 0.0f, 1.0f);
push.pos2 = glm::vec4(0.0f, 0.05f, 0.0f, 1.0f);
device_->CmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(DebugPush), &push);
device_->CmdDraw(draw_buffer, 2, 1, 0, 0);
device_->cmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(DebugPush), &push);
device_->cmdDraw(draw_buffer, 2, 1, 0, 0);
device_->CmdRenderImguiDrawData(draw_buffer, ImGui::GetDrawData());
device_->cmdRenderImguiDrawData(draw_buffer, ImGui::GetDrawData());
device_->FinishRender(draw_buffer);
device_->finishRender(draw_buffer);
}
void Renderer::DrawRenderList(gfx::DrawBuffer* draw_buffer, const RenderList& render_list)
@ -351,22 +353,22 @@ void Renderer::DrawRenderList(gfx::DrawBuffer* draw_buffer, const RenderList& re
if (last_bound_pipeline_ == nullptr) {
const gfx::Pipeline* first_pipeline = render_list.begin()->pipeline;
// these bindings persist between all pipelines
device_->CmdBindDescriptorSet(draw_buffer, first_pipeline, global_uniform.set, 0);
device_->CmdBindDescriptorSet(draw_buffer, first_pipeline, frame_uniform.set, 1);
device_->CmdBindPipeline(draw_buffer, first_pipeline);
device_->cmdBindDescriptorSet(draw_buffer, first_pipeline, global_uniform.set, 0);
device_->cmdBindDescriptorSet(draw_buffer, first_pipeline, frame_uniform.set, 1);
device_->cmdBindPipeline(draw_buffer, first_pipeline);
last_bound_pipeline_ = first_pipeline;
}
for (const auto& entry : render_list) {
if (entry.pipeline != last_bound_pipeline_) {
device_->CmdBindPipeline(draw_buffer, entry.pipeline);
device_->cmdBindPipeline(draw_buffer, entry.pipeline);
last_bound_pipeline_ = entry.pipeline;
}
device_->CmdBindDescriptorSet(draw_buffer, entry.pipeline, entry.material_set, 2);
device_->CmdPushConstants(draw_buffer, entry.pipeline, 0, sizeof(entry.model_matrix), &entry.model_matrix);
device_->CmdBindVertexBuffer(draw_buffer, 0, entry.vertex_buffer);
device_->CmdBindIndexBuffer(draw_buffer, entry.index_buffer);
device_->CmdDrawIndexed(draw_buffer, entry.index_count, 1, 0, 0, 0);
device_->cmdBindDescriptorSet(draw_buffer, entry.pipeline, entry.material_set, 2);
device_->cmdPushConstants(draw_buffer, entry.pipeline, 0, sizeof(entry.model_matrix), &entry.model_matrix);
device_->cmdBindVertexBuffer(draw_buffer, 0, entry.vertex_buffer);
device_->cmdBindIndexBuffer(draw_buffer, entry.index_buffer);
device_->cmdDrawIndexed(draw_buffer, entry.index_count, 1, 0, 0, 0);
}
}

View File

@ -12,7 +12,7 @@ namespace engine {
Font::Font(const std::string& path)
{
m_font_buffer = ReadBinaryFile(path);
m_font_buffer = readBinaryFile(path);
m_font_info = std::make_unique<stbtt_fontinfo>();
if (stbtt_InitFont(m_font_info.get(), m_font_buffer->data(), 0) == 0) {

View File

@ -7,27 +7,27 @@ namespace engine {
Material::Material(Renderer* renderer, std::shared_ptr<Shader> shader) : m_shader(shader), m_renderer(renderer)
{
m_material_set = renderer->GetDevice()->AllocateDescriptorSet(renderer->GetMaterialSetLayout());
m_material_set = renderer->GetDevice()->allocateDescriptorSet(renderer->GetMaterialSetLayout());
LOG_DEBUG("Created material");
}
Material::~Material() { m_renderer->GetDevice()->FreeDescriptorSet(m_material_set); LOG_DEBUG("Destroyed material"); }
Material::~Material() { m_renderer->GetDevice()->freeDescriptorSet(m_material_set); LOG_DEBUG("Destroyed material"); }
void Material::setAlbedoTexture(std::shared_ptr<Texture> texture)
{
m_renderer->GetDevice()->UpdateDescriptorCombinedImageSampler(m_material_set, 0, texture->GetImage(), texture->GetSampler());
m_renderer->GetDevice()->updateDescriptorCombinedImageSampler(m_material_set, 0, texture->GetImage(), texture->GetSampler());
m_texture_albedo = texture;
}
void Material::setNormalTexture(std::shared_ptr<Texture> texture)
{
m_renderer->GetDevice()->UpdateDescriptorCombinedImageSampler(m_material_set, 1, texture->GetImage(), texture->GetSampler());
m_renderer->GetDevice()->updateDescriptorCombinedImageSampler(m_material_set, 1, texture->GetImage(), texture->GetSampler());
m_texture_normal = texture;
}
void Material::setOcclusionRoughnessMetallicTexture(std::shared_ptr<Texture> texture)
{
m_renderer->GetDevice()->UpdateDescriptorCombinedImageSampler(m_material_set, 2, texture->GetImage(), texture->GetSampler());
m_renderer->GetDevice()->updateDescriptorCombinedImageSampler(m_material_set, 2, texture->GetImage(), texture->GetSampler());
m_texture_occlusion_roughness_metallic = texture;
}

View File

@ -18,8 +18,8 @@ Mesh::Mesh(GFXDevice* gfx, const std::vector<Vertex>& vertices, const std::vecto
Mesh::~Mesh()
{
m_gfx->DestroyBuffer(m_ib);
m_gfx->DestroyBuffer(m_vb);
m_gfx->destroyBuffer(m_ib);
m_gfx->destroyBuffer(m_vb);
LOG_DEBUG("Destroyed mesh");
}
@ -31,8 +31,8 @@ uint32_t Mesh::getCount() { return m_count; }
void Mesh::initMesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices)
{
m_vb = m_gfx->CreateBuffer(gfx::BufferType::kVertex, vertices.size() * sizeof(Vertex), vertices.data());
m_ib = m_gfx->CreateBuffer(gfx::BufferType::kIndex, indices.size() * sizeof(uint32_t), indices.data());
m_vb = m_gfx->createBuffer(gfx::BufferType::VERTEX, vertices.size() * sizeof(Vertex), vertices.data());
m_ib = m_gfx->createBuffer(gfx::BufferType::INDEX, indices.size() * sizeof(uint32_t), indices.data());
m_count = (uint32_t)indices.size();
LOG_DEBUG("Created mesh, vertices: {}, indices: {}", vertices.size(), indices.size());
}

View File

@ -19,27 +19,27 @@ Shader::Shader(Renderer* renderer, const std::string& vertPath, const std::strin
gfx::VertexFormat vertFormat{};
vertFormat.attribute_descriptions.emplace_back(
index++, gfx::VertexAttribFormat::kFloat3, stride);
index++, gfx::VertexAttribFormat::FLOAT3, stride);
stride += 3 * sizeof(float);
if (settings.vertexParams.has_normal) {
vertFormat.attribute_descriptions.emplace_back(
index++, gfx::VertexAttribFormat::kFloat3, stride);
index++, gfx::VertexAttribFormat::FLOAT3, stride);
stride += 3 * sizeof(float);
}
if (settings.vertexParams.has_tangent) {
vertFormat.attribute_descriptions.emplace_back(
index++, gfx::VertexAttribFormat::kFloat4, stride);
index++, gfx::VertexAttribFormat::FLOAT4, stride);
stride += 4 * sizeof(float);
}
if (settings.vertexParams.has_color) {
vertFormat.attribute_descriptions.emplace_back(
index++, gfx::VertexAttribFormat::kFloat4, stride);
index++, gfx::VertexAttribFormat::FLOAT4, stride);
stride += 4 * sizeof(float);
}
if (settings.vertexParams.has_uv0) {
vertFormat.attribute_descriptions.emplace_back(
index++, gfx::VertexAttribFormat::kFloat2, stride);
index++, gfx::VertexAttribFormat::FLOAT2, stride);
stride += 2 * sizeof(float);
}
vertFormat.stride = stride;
@ -49,21 +49,21 @@ Shader::Shader(Renderer* renderer, const std::string& vertPath, const std::strin
info.frag_shader_path = fragPath;
info.vertex_format = vertFormat;
info.alpha_blending = settings.alpha_blending;
info.face_cull_mode = settings.cull_backface ? gfx::CullMode::kCullBack : gfx::CullMode::kCullNone;
info.face_cull_mode = settings.cull_backface ? gfx::CullMode::CULL_BACK : gfx::CullMode::CULL_NONE;
info.write_z = settings.write_z;
info.line_primitives = false;
info.descriptor_set_layouts.push_back(renderer->GetGlobalSetLayout());
info.descriptor_set_layouts.push_back(renderer->GetFrameSetLayout());
info.descriptor_set_layouts.push_back(renderer->GetMaterialSetLayout());
pipeline_ = gfx_->CreatePipeline(info);
pipeline_ = gfx_->createPipeline(info);
LOG_DEBUG("Created shader: {}, pipeline: {}", vertPath,
static_cast<const void*>(pipeline_));
}
Shader::~Shader() {
gfx_->DestroyPipeline(pipeline_);
gfx_->destroyPipeline(pipeline_);
LOG_DEBUG("Destroyed shader, pipeline: {}", static_cast<const void*>(pipeline_));
}

View File

@ -12,12 +12,12 @@ namespace engine {
Texture::Texture(Renderer* renderer, const uint8_t* bitmap, int width, int height, gfx::SamplerInfo samplerInfo, bool srgb) : gfx_(renderer->GetDevice())
{
if (renderer->samplers.contains(samplerInfo) == false) {
renderer->samplers.insert(std::make_pair(samplerInfo, gfx_->CreateSampler(samplerInfo)));
renderer->samplers.insert(std::make_pair(samplerInfo, gfx_->createSampler(samplerInfo)));
}
gfx::ImageFormat format = srgb ? gfx::ImageFormat::kSRGB : gfx::ImageFormat::kLinear;
gfx::ImageFormat format = srgb ? gfx::ImageFormat::SRGB : gfx::ImageFormat::LINEAR;
image_ = gfx_->CreateImage(width, height, format, bitmap);
image_ = gfx_->createImage(width, height, format, bitmap);
sampler_ = renderer->samplers.at(samplerInfo);
LOG_DEBUG("Created texture: width: {}, height: {}", width, height);
@ -25,14 +25,14 @@ Texture::Texture(Renderer* renderer, const uint8_t* bitmap, int width, int heigh
Texture::~Texture()
{
gfx_->DestroyImage(image_);
gfx_->destroyImage(image_);
LOG_DEBUG("Destroyed texture");
}
std::unique_ptr<Texture> LoadTextureFromFile(const std::string& path, gfx::SamplerInfo samplerInfo, Renderer* renderer, bool srgb)
{
int width, height;
auto bitmap = ReadImageFile(path, width, height);
auto bitmap = readImageFile(path, width, height);
return std::make_unique<Texture>(renderer, bitmap->data(), width, height, samplerInfo, srgb);
}

View File

@ -64,7 +64,7 @@ void Scene::Update(float ts) {
system->onUpdate(ts);
}
event_system_->DespatchEvents(); // clears event queue
event_system_->despatchEvents(); // clears event queue
}
} // namespace engine

View File

@ -55,13 +55,13 @@ namespace engine {
VkPresentModeKHR present_mode_requested;
switch (info.requested_present_mode) {
case gfx::PresentMode::kDoubleBufferedNoVsync:
case gfx::PresentMode::DOUBLE_BUFFERED_NO_VSYNC:
present_mode_requested = VK_PRESENT_MODE_IMMEDIATE_KHR;
break;
case gfx::PresentMode::kDoubleBufferedVsync:
case gfx::PresentMode::DOUBLE_BUFFERED_VSYNC:
present_mode_requested = VK_PRESENT_MODE_FIFO_KHR;
break;
case gfx::PresentMode::kTripleBuffered:
case gfx::PresentMode::TRIPLE_BUFFERED:
present_mode_requested = VK_PRESENT_MODE_MAILBOX_KHR;
}
sc->presentMode = VK_PRESENT_MODE_FIFO_KHR; // This mode is always available

View File

@ -62,7 +62,7 @@ void CameraControllerSystem::onUpdate(float ts)
// keep vel.z as gravity can increase it every frame
// gravity stuff here:
c->vel.z += CameraControllerComponent::kGravAccel * dt;
c->vel.z += c->grav_accel * dt;
// jumping
if (m_scene->app()->getInputManager()->GetButtonPress("jump") && (c->grounded || c->noclip)) {
@ -208,6 +208,15 @@ void CameraControllerSystem::onUpdate(float ts)
c->noclip ^= true;
}
if (m_scene->app()->getWindow()->GetKeyPress(engine::inputs::Key::K_T)) {
if (c->grav_accel != 0.0f) {
c->grav_accel = 0.0f;
}
else {
c->grav_accel = -9.81f;
}
}
if (m_scene->app()->getWindow()->GetButtonPress(engine::inputs::MouseButton::M_LEFT)) {
engine::Ray ray{};
ray.origin = t->position;

View File

@ -25,8 +25,8 @@ struct CameraControllerComponent {
static constexpr float kMaxStairHeight = 0.2f;
static constexpr size_t kNumHorizontalRays = 20;
static constexpr float kGravAccel = -9.81f;
// static constexpr float kGravAccel = -1.625f; // moon gravity
float grav_accel = -9.81f;
// grav_accel = -1.625f; // moon gravity
static constexpr float kMaxDistanceFromOrigin = 200.0f;
bool noclip = false;

View File

@ -47,9 +47,9 @@ void PlayGame(GameSettings settings)
engine::gfx::GraphicsSettings graphics_settings{};
graphics_settings.enable_validation = settings.enable_validation;
graphics_settings.present_mode = engine::gfx::PresentMode::kTripleBuffered;
graphics_settings.msaa_level = engine::gfx::MSAALevel::kOff;
graphics_settings.enable_anisotropy = true;
graphics_settings.present_mode = engine::gfx::PresentMode::TRIPLE_BUFFERED;
graphics_settings.msaa_level = engine::gfx::MSAALevel::MSAA_OFF;
graphics_settings.enable_anisotropy = false;
engine::AppConfiguration configuration{};
configuration.enable_frame_limiter = settings.enable_frame_limiter;
@ -66,7 +66,7 @@ void PlayGame(GameSettings settings)
/* as of right now, the entity with tag 'camera' is used to build the view
* matrix */
//engine::Entity temple = engine::util::LoadGLTF(*start_scene, "C:/games/temple.glb", true);
//engine::Entity temple = engine::loadGLTF(*start_scene, "C:/games/temple.glb", true);
start_scene->RegisterComponent<CameraControllerComponent>();
start_scene->RegisterSystemAtIndex<CameraControllerSystem>(0);
@ -98,36 +98,38 @@ void PlayGame(GameSettings settings)
main_scene->AddComponent<CameraControllerComponent>(camera);
/* floor */
engine::Entity floor = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/floor2.glb"), true);
engine::Entity floor = engine::loadGLTF(*main_scene, app.getResourcePath("models/floor2.glb"), true);
main_scene->GetScale(floor).x *= 100.0f;
main_scene->GetScale(floor).z *= 100.0f;
//main_scene->GetComponent<engine::MeshRenderableComponent>(main_scene->GetEntity("Cube", floor))->visible = false;
engine::Entity monke = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/monke.glb"), true);
engine::Entity monke = engine::loadGLTF(*main_scene, app.getResourcePath("models/monke.glb"), true);
main_scene->GetComponent<engine::TransformComponent>(monke)->position.y += 10.0f;
// engine::Entity bottle = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/bottle.glb"));
// engine::Entity bottle = engine::loadGLTF(*main_scene, app.getResourcePath("models/bottle.glb"));
// main_scene->GetComponent<engine::TransformComponent>(bottle)->scale *= 10.0f;
// main_scene->GetComponent<engine::TransformComponent>(bottle)->position.x += 25.0f;
// main_scene->GetComponent<engine::TransformComponent>(bottle)->position.z += 5.0f;
engine::Entity helmet = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/DamagedHelmet.glb"), true);
engine::Entity helmet = engine::loadGLTF(*main_scene, app.getResourcePath("models/DamagedHelmet.glb"), true);
main_scene->GetPosition(helmet) += glm::vec3{5.0f, 5.0f, 5.0f};
main_scene->GetScale(helmet) *= 3.0f;
main_scene->GetRotation(helmet) = glm::angleAxis(glm::pi<float>(), glm::vec3{ 0.0f, 0.0f, 1.0f });
main_scene->GetRotation(helmet) *= glm::angleAxis(glm::half_pi<float>(), glm::vec3{ 1.0f, 0.0f, 0.0f });
engine::Entity toycar = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/ToyCar.glb"), true);
engine::Entity toycar = engine::loadGLTF(*main_scene, app.getResourcePath("models/ToyCar.glb"), true);
main_scene->GetScale(toycar) *= 150.0f;
main_scene->GetPosition(toycar).z -= 0.07f;
engine::Entity stairs = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/stairs.glb"), true);
engine::Entity stairs = engine::loadGLTF(*main_scene, app.getResourcePath("models/stairs.glb"), true);
main_scene->GetPosition(stairs) += glm::vec3{-8.0f, -5.0f, 0.1f};
main_scene->GetRotation(stairs) = glm::angleAxis(glm::half_pi<float>(), glm::vec3{0.0f, 0.0f, 1.0f});
main_scene->GetRotation(stairs) *= glm::angleAxis(glm::half_pi<float>(), glm::vec3{1.0f, 0.0f, 0.0f});
engine::Entity axes = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/MY_AXES.glb"), true);
engine::Entity axes = engine::loadGLTF(*main_scene, app.getResourcePath("models/MY_AXES.glb"), true);
main_scene->GetPosition(axes) += glm::vec3{-40.0f, -40.0f, 1.0f};
engine::Entity bottle = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/bottle.glb"), true);
engine::Entity bottle = engine::loadGLTF(*main_scene, app.getResourcePath("models/bottle.glb"), true);
main_scene->GetPosition(bottle).y -= 10.0f;
main_scene->GetPosition(bottle).z += 2.5f;
main_scene->GetScale(bottle) *= 25.0f;
@ -149,15 +151,15 @@ void PlayGame(GameSettings settings)
};
engine::Entity teapot = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/teapot.glb"), true);
engine::Entity teapot = engine::loadGLTF(*main_scene, app.getResourcePath("models/teapot.glb"), true);
main_scene->GetPosition(teapot).y += 5.0f;
main_scene->GetPosition(teapot).x -= 5.0f;
main_scene->GetScale(teapot) *= 5.0f;
engine::Entity tree = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/tree.glb"), true);
engine::Entity tree = engine::loadGLTF(*main_scene, app.getResourcePath("models/tree.glb"), true);
main_scene->GetPosition(tree) = glm::vec3{-5.0f, -5.0f, 0.0f};
engine::Entity box = engine::util::LoadGLTF(*main_scene, app.getResourcePath("models/box.glb"), true);
engine::Entity box = engine::loadGLTF(*main_scene, app.getResourcePath("models/box.glb"), true);
main_scene->GetPosition(box) = glm::vec3{ -5.0f, -17.0f, 0.1f };
main_scene->GetScale(box) *= 10.0f;
main_scene->GetRotation(box) = glm::angleAxis(glm::pi<float>() * 0.0f, glm::vec3{ 0.0f, 0.0f, 1.0f });

View File

@ -73,7 +73,7 @@ std::unique_ptr<engine::Mesh> GenSphereMesh(engine::GFXDevice* gfx, float r, int
}
}
std::vector<uint32_t> indices = engine::util::GenTangents(vertices);
std::vector<uint32_t> indices = engine::genTangents(vertices);
return std::make_unique<engine::Mesh>(gfx, vertices, indices);
}
@ -137,7 +137,7 @@ std::unique_ptr<engine::Mesh> GenCuboidMesh(engine::GFXDevice* gfx, float x, flo
}
}
std::vector<uint32_t> indices = engine::util::GenTangents(vertices);
std::vector<uint32_t> indices = engine::genTangents(vertices);
return std::make_unique<engine::Mesh>(gfx, vertices, indices);
}