diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 3a54a67..c8cbc3c 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -10,6 +10,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/editor.xml b/.idea/editor.xml
index 660ebdf..e3a1c4e 100644
--- a/.idea/editor.xml
+++ b/.idea/editor.xml
@@ -1,19 +1,33 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/editor/shaders/triangle.frag b/src/editor/shaders/triangle.frag
index 223775f..1cca3f7 100644
--- a/src/editor/shaders/triangle.frag
+++ b/src/editor/shaders/triangle.frag
@@ -5,8 +5,9 @@ layout(location = 1) in vec2 uv;
layout(location = 0) out vec4 color;
-layout(binding = 1) uniform sampler2D albedo;
+layout(binding = 1) uniform sampler2D diffuse;
void main() {
- color = texture(albedo, uv) * vec4(vertex_color, 1.0);
-}
\ No newline at end of file
+ color = vec4(vertex_color, 1.0);
+ color = texture(diffuse, uv);
+}
diff --git a/src/editor/shaders/triangle.vert b/src/editor/shaders/triangle.vert
index 03b5c22..6acae38 100644
--- a/src/editor/shaders/triangle.vert
+++ b/src/editor/shaders/triangle.vert
@@ -17,4 +17,4 @@ void main() {
gl_Position = mvp.projection * mvp.view * mvp.model * vec4(position, 1.0);
out_color = color;
out_uv = uv;
-}
\ No newline at end of file
+}
diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt
index ace4a4a..2e6710b 100644
--- a/src/engine/CMakeLists.txt
+++ b/src/engine/CMakeLists.txt
@@ -1,7 +1,7 @@
project("Vixen Engine")
+find_package(GLFW3 3.3 REQUIRED)
pkg_check_modules(GLM REQUIRED IMPORTED_TARGET glm)
-pkg_check_modules(GLFW REQUIRED IMPORTED_TARGET glfw3)
pkg_check_modules(ASSIMP REQUIRED IMPORTED_TARGET assimp)
pkg_check_modules(SPDLOG REQUIRED IMPORTED_TARGET spdlog)
@@ -14,13 +14,15 @@ set(
Camera.cpp
)
-link_libraries(
+add_library(Vixen STATIC ${SOURCES})
+target_link_libraries(
+ Vixen
+ PUBLIC
+ glfw
PkgConfig::GLM
- PkgConfig::GLFW
PkgConfig::ASSIMP
PkgConfig::SPDLOG
)
-add_library(Vixen STATIC ${SOURCES})
if (ENABLE_VULKAN)
add_subdirectory(vk)
diff --git a/src/engine/Camera.cpp b/src/engine/Camera.cpp
index 261daa7..cf80e78 100644
--- a/src/engine/Camera.cpp
+++ b/src/engine/Camera.cpp
@@ -1,34 +1,47 @@
#include "Camera.h"
namespace Vixen {
- Camera::Camera(const glm::vec3 position, const float fieldOfView, const float nearPlane, const float farPlane,
- const glm::vec3 clearColor)
- : position(position),
- // rotation(glm::quat{}),
- rotation({}),
- fieldOfView(fieldOfView),
- nearPlane(nearPlane),
- farPlane(farPlane),
- clearColor(clearColor) {}
+ Camera::Camera(
+ const glm::vec3 position,
+ const glm::vec3 rotation,
+ const float fieldOfView,
+ const float nearPlane,
+ const float farPlane
+ ) : position(position),
+ rotation(rotation),
+ fieldOfView(fieldOfView),
+ nearPlane(nearPlane),
+ farPlane(farPlane) {}
+ /**
+ * \brief Calculates the view matrix for this camera.
+ * \return Returns the view matrix.
+ */
glm::mat4 Camera::view() const {
- // glm::vec3 front;
- // front.x = static_cast(cos(glm::radians(rotation.x)) * cos(glm::radians(rotation.y)));
- // front.y = static_cast(sin(glm::radians(rotation.y)));
- // front.z = static_cast(sin(glm::radians(rotation.x)) * cos(glm::radians(rotation.y)));
- //
- // front = normalize(front);
- // const auto &right = normalize(cross(front, glm::vec3(0.0f, 1.0f, 0.0f)));
- // const auto &up = normalize(cross(right, front));
- //
- // return lookAt(position, position + front, up);
+ const auto& direction = normalize(glm::vec3(
+ cos(rotation.x) * sin(rotation.y),
+ sin(rotation.y),
+ cos(rotation.x) * cos(rotation.y)
+ ));
+ const auto& right = normalize(glm::vec3(
+ sin(rotation.y - M_PI / 2.0f),
+ 0.0f,
+ cos(rotation.y - M_PI / 2.0f)
+ ));
+ const auto& up = cross(right, direction);
+
return lookAt(
position,
- glm::vec3(0, 0, 0),
- {0.0f, 1.0f, 0.0f}
+ position + direction,
+ up
);
}
+ /**
+ * \brief Calculates the perspective matrix for a given aspect ratio and the current camera's settings.
+ * \param aspectRatio The aspect ratio (width / height) in degrees.
+ * \return Returns the perspective matrix for the given aspect ratio and camera settings.
+ */
glm::mat4 Camera::perspective(const float aspectRatio) const {
return glm::perspective(
glm::radians(fieldOfView),
@@ -42,12 +55,7 @@ namespace Vixen {
return position;
}
- // const glm::quat &Camera::getRotation() const {
- // return rotation;
- // }
-
glm::vec3 Camera::getEulerRotation() const {
- // return glm::eulerAngles(rotation);
return rotation;
}
@@ -58,8 +66,4 @@ namespace Vixen {
float Camera::getFarPlane() const {
return farPlane;
}
-
- const glm::vec3& Camera::getClearColor() const {
- return clearColor;
- }
}
diff --git a/src/engine/Camera.h b/src/engine/Camera.h
index 413c309..18b014f 100644
--- a/src/engine/Camera.h
+++ b/src/engine/Camera.h
@@ -5,14 +5,15 @@
#include
namespace Vixen {
+ // TODO: Ideally, the camera should be quaternion based and not euler-angles based.
class Camera {
public:
explicit Camera(
glm::vec3 position = {},
- float fieldOfView = 114.0f,
+ glm::vec3 rotation = {M_PI, 0.0f, 0.0f},
+ float fieldOfView = 90.0f,
float nearPlane = 0.1f,
- float farPlane = 1000.0f,
- glm::vec3 clearColor = {0.0f, 0.0f, 0.0f}
+ float farPlane = 1000.0f
);
[[nodiscard]] glm::mat4 view() const;
@@ -21,20 +22,15 @@ namespace Vixen {
[[nodiscard]] const glm::vec3& getPosition() const;
- // [[nodiscard]] const glm::quat &getRotation() const;
-
[[nodiscard]] glm::vec3 getEulerRotation() const;
[[nodiscard]] float getNearPlane() const;
[[nodiscard]] float getFarPlane() const;
- [[nodiscard]] const glm::vec3& getClearColor() const;
-
private:
glm::vec3 position;
- //glm::quat rotation;
glm::vec3 rotation;
float fieldOfView;
@@ -42,7 +38,5 @@ namespace Vixen {
float nearPlane;
float farPlane;
-
- glm::vec3 clearColor;
};
}
diff --git a/src/engine/Vixen.h b/src/engine/Vixen.h
index 7b06481..e3bf42f 100644
--- a/src/engine/Vixen.h
+++ b/src/engine/Vixen.h
@@ -6,11 +6,11 @@
namespace Vixen {
class Vixen {
- public:
const std::string appTitle;
const glm::vec3 appVersion;
+ public:
Vixen(std::string appTitle, const glm::vec3 appVersion)
: appTitle(std::move(appTitle)), appVersion(appVersion) {}
};
diff --git a/src/engine/Window.cpp b/src/engine/Window.cpp
index a703819..a53dbbd 100644
--- a/src/engine/Window.cpp
+++ b/src/engine/Window.cpp
@@ -1,14 +1,13 @@
-#include
#include "Window.h"
namespace Vixen {
Window::Window(
- const std::string &title,
- const uint32_t &width,
- const uint32_t &height,
- bool transparentFrameBuffer
+ const std::string& title,
+ const uint32_t& width,
+ const uint32_t& height,
+ const bool transparentFrameBuffer
) : window(nullptr) {
- glfwSetErrorCallback([](int code, const char *message) {
+ glfwSetErrorCallback([](int code, const char* message) {
spdlog::error("[GLFW] {} ({})", message, code);
});
@@ -17,21 +16,21 @@ namespace Vixen {
int count;
auto primary = glfwGetPrimaryMonitor();
- auto glfwMonitors = glfwGetMonitors(&count);
+ const auto glfwMonitors = glfwGetMonitors(&count);
monitor = glfwGetPrimaryMonitor(); // TODO
for (int i = 0; i < count; i++) {
- const auto &m = glfwMonitors[i];
- const auto &mode = glfwGetVideoMode(m);
+ const auto& m = glfwMonitors[i];
+ const auto& mode = glfwGetVideoMode(m);
monitors[m] = Monitor{
- std::string(glfwGetMonitorName(m)),
- mode->width,
- mode->height,
- mode->refreshRate,
- mode->blueBits,
- mode->redBits,
- mode->greenBits,
- primary == m
+ std::string(glfwGetMonitorName(m)),
+ mode->width,
+ mode->height,
+ mode->refreshRate,
+ mode->blueBits,
+ mode->redBits,
+ mode->greenBits,
+ primary == m
};
}
@@ -52,7 +51,7 @@ namespace Vixen {
glfwSetWindowUserPointer(window, this);
glfwSetFramebufferSizeCallback(window, [](auto w, auto width, auto height) {
- auto wind = static_cast(glfwGetWindowUserPointer(w));
+ auto wind = static_cast(glfwGetWindowUserPointer(w));
wind->framebufferSizeChanged = true;
});
}
@@ -63,6 +62,11 @@ namespace Vixen {
glfwTerminate();
}
+ GLFWwindow* Window::getWindow() const { return window; }
+
+ bool Window::isFramebufferSizeChanged() const { return framebufferSizeChanged; }
+
+
bool Window::shouldClose() const {
return glfwWindowShouldClose(window) == GLFW_TRUE;
}
@@ -104,17 +108,17 @@ namespace Vixen {
void Window::center() const {
uint32_t w;
uint32_t h;
- glfwGetWindowSize(window, reinterpret_cast(&w), reinterpret_cast(&h));
+ glfwGetWindowSize(window, reinterpret_cast(&w), reinterpret_cast(&h));
const auto mode = glfwGetVideoMode(monitor);
uint32_t x;
uint32_t y;
- glfwGetMonitorPos(monitor, reinterpret_cast(&x), reinterpret_cast(&y));
+ glfwGetMonitorPos(monitor, reinterpret_cast(&x), reinterpret_cast(&y));
glfwSetWindowPos(
- window,
- static_cast(x) + mode->width / 2 - w / 2,
- static_cast(y) + mode->height / 2 - h / 2
+ window,
+ static_cast(x) + mode->width / 2 - w / 2,
+ static_cast(y) + mode->height / 2 - h / 2
);
}
@@ -122,22 +126,22 @@ namespace Vixen {
if (monitor == nullptr)
return nullptr;
- const auto &primary = glfwGetPrimaryMonitor();
- const auto &mode = glfwGetVideoMode(monitor);
+ const auto& primary = glfwGetPrimaryMonitor();
+ const auto& mode = glfwGetVideoMode(monitor);
return std::make_unique(Monitor{
- std::string(glfwGetMonitorName(monitor)),
- mode->width,
- mode->height,
- mode->refreshRate,
- mode->blueBits,
- mode->redBits,
- mode->greenBits,
- primary == monitor
+ std::string(glfwGetMonitorName(monitor)),
+ mode->width,
+ mode->height,
+ mode->refreshRate,
+ mode->blueBits,
+ mode->redBits,
+ mode->greenBits,
+ primary == monitor
});
}
- std::unordered_map Window::getMonitors() const {
+ std::unordered_map Window::getMonitors() const {
return monitors;
}
@@ -147,7 +151,7 @@ namespace Vixen {
int x;
int y;
int refreshRate;
- GLFWmonitor *m;
+ GLFWmonitor* m;
if (mode == Mode::FULLSCREEN) {
auto videoMode = glfwGetVideoMode(monitor);
@@ -158,14 +162,16 @@ namespace Vixen {
glfwSetWindowAttrib(window, GLFW_DECORATED, false);
glfwSetWindowAttrib(window, GLFW_FLOATING, true);
- } else if (mode == Mode::BORDERLESS_FULLSCREEN) {
+ }
+ else if (mode == Mode::BORDERLESS_FULLSCREEN) {
auto videoMode = glfwGetVideoMode(monitor);
w = videoMode->width;
h = videoMode->height;
glfwSetWindowAttrib(window, GLFW_DECORATED, false);
glfwSetWindowAttrib(window, GLFW_FLOATING, true);
- } else {
+ }
+ else {
glfwGetWindowPos(window, &x, &y);
glfwGetWindowSize(window, &w, &h);
glfwSetWindowAttrib(window, GLFW_DECORATED, true);
@@ -175,7 +181,7 @@ namespace Vixen {
glfwSetWindowMonitor(window, m, x, y, w, h, refreshRate);
}
- void Window::getFramebufferSize(int &width, int &height) {
+ void Window::getFramebufferSize(int& width, int& height) {
glfwGetFramebufferSize(window, &width, &height);
}
diff --git a/src/engine/Window.h b/src/engine/Window.h
index fe53e5e..aa94d54 100644
--- a/src/engine/Window.h
+++ b/src/engine/Window.h
@@ -1,12 +1,20 @@
#pragma once
-#include
#include
+#include
#include
#include "Monitor.h"
namespace Vixen {
class Window {
+ GLFWmonitor* monitor;
+
+ GLFWwindow* window;
+
+ std::unordered_map monitors;
+
+ bool framebufferSizeChanged = false;
+
public:
enum class Mode {
FULLSCREEN,
@@ -14,23 +22,23 @@ namespace Vixen {
WINDOWED,
};
- protected:
- GLFWmonitor *monitor;
-
- GLFWwindow *window;
-
- std::unordered_map monitors;
-
- public:
Window(
- const std::string &title,
- const uint32_t &width,
- const uint32_t &height,
- bool transparentFrameBuffer
+ const std::string& title,
+ const uint32_t& width,
+ const uint32_t& height,
+ bool transparentFrameBuffer
);
+ Window(const Window&) = delete;
+
+ Window& operator=(const Window&) = delete;
+
~Window();
+ [[nodiscard]] GLFWwindow* getWindow() const;
+
+ [[nodiscard]] bool isFramebufferSizeChanged() const;
+
/**
* Has the current window been requested to close?
* @return True if the window should close, false if not.
@@ -60,11 +68,8 @@ namespace Vixen {
std::unique_ptr getMonitor() const;
- std::unordered_map getMonitors() const;
+ std::unordered_map getMonitors() const;
- void getFramebufferSize(int &width, int &height);
-
- private:
- bool framebufferSizeChanged = false;
+ void getFramebufferSize(int& width, int& height);
};
}
diff --git a/src/engine/vk/Swapchain.h b/src/engine/vk/Swapchain.h
index 978d1bc..212fb19 100644
--- a/src/engine/vk/Swapchain.h
+++ b/src/engine/vk/Swapchain.h
@@ -2,7 +2,6 @@
#include
#include "Device.h"
-#include "VkFence.h"
#include "VkSemaphore.h"
namespace Vixen::Vk {
diff --git a/src/engine/vk/VkPipeline.cpp b/src/engine/vk/VkPipeline.cpp
index 2b56717..d4c7cbb 100644
--- a/src/engine/vk/VkPipeline.cpp
+++ b/src/engine/vk/VkPipeline.cpp
@@ -3,13 +3,12 @@
namespace Vixen::Vk {
VkPipeline::VkPipeline(
const std::shared_ptr& device,
- const Swapchain& swapchain,
const VkShaderProgram& program,
const Config& config
) : device(device),
program(program),
config(config),
- renderPass(device, program, swapchain),
+ renderPass(device, config.format),
pipelineLayout(device, program) {
std::vector stages;
stages.emplace_back(program.getVertex()->createInfo());
@@ -173,15 +172,11 @@ namespace Vixen::Vk {
bind(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
}
- const VkShaderProgram& VkPipeline::getProgram() const {
- return program;
- }
+ const VkShaderProgram& VkPipeline::getProgram() const { return program; }
- const VkRenderPass& VkPipeline::getRenderPass() const {
- return renderPass;
- }
+ const VkRenderPass& VkPipeline::getRenderPass() const { return renderPass; }
- const VkPipeline::Config& VkPipeline::getConfig() const {
- return config;
- }
+ const VkPipeline::Config& VkPipeline::getConfig() const { return config; }
+
+ std::shared_ptr VkPipeline::getDevice() const { return device; }
}
diff --git a/src/engine/vk/VkPipeline.h b/src/engine/vk/VkPipeline.h
index 9d67f6e..44babe8 100644
--- a/src/engine/vk/VkPipeline.h
+++ b/src/engine/vk/VkPipeline.h
@@ -2,7 +2,6 @@
#include "Device.h"
#include "VkShaderProgram.h"
-#include "Swapchain.h"
#include "VkPipelineLayout.h"
#include "VkRenderPass.h"
@@ -19,6 +18,7 @@ namespace Vixen::Vk {
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
VkPipelineDepthStencilStateCreateInfo depthStencilInfo{};
uint32_t subpass = 0;
+ VkFormat format = VK_FORMAT_UNDEFINED;
};
protected:
@@ -35,8 +35,11 @@ namespace Vixen::Vk {
::VkPipeline pipeline = VK_NULL_HANDLE;
public:
- VkPipeline(const std::shared_ptr &device, const Swapchain &swapchain, const VkShaderProgram &program,
- const Config &config);
+ VkPipeline(
+ const std::shared_ptr& device,
+ const VkShaderProgram& program,
+ const Config& config
+ );
VkPipeline(VkPipeline& other) = delete;
@@ -56,123 +59,129 @@ namespace Vixen::Vk {
void bindRayTracing(::VkCommandBuffer commandBuffer) const;
- [[nodiscard]] const VkShaderProgram &getProgram() const;
+ [[nodiscard]] const VkShaderProgram& getProgram() const;
- [[nodiscard]] const VkRenderPass &getRenderPass() const;
+ [[nodiscard]] const VkRenderPass& getRenderPass() const;
- [[nodiscard]] const Config &getConfig() const;
+ [[nodiscard]] const Config& getConfig() const;
+
+ [[nodiscard]] std::shared_ptr getDevice() const;
class Builder {
Config config{
- .viewport = {
- .x = 0,
- .y = 0,
- .minDepth = 0.0f,
- .maxDepth = 1.0f
- },
- .scissor = {
- .offset = {0, 0},
- }
+ .viewport = {
+ .x = 0,
+ .y = 0,
+ .minDepth = 0.0f,
+ .maxDepth = 1.0f
+ },
+ .scissor = {
+ .offset = {0, 0},
+ }
};
public:
Builder() {
config.inputAssemblyInfo = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
- .primitiveRestartEnable = VK_FALSE
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+ .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+ .primitiveRestartEnable = VK_FALSE
};
config.rasterizationInfo = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .depthClampEnable = VK_FALSE,
- .rasterizerDiscardEnable = VK_FALSE,
- .polygonMode = VK_POLYGON_MODE_FILL,
- .cullMode = VK_CULL_MODE_BACK_BIT,
- .frontFace = VK_FRONT_FACE_CLOCKWISE,
- .depthBiasEnable = VK_FALSE,
- .depthBiasConstantFactor = 0.0f,
- .depthBiasClamp = 0.0f,
- .depthBiasSlopeFactor = 0.0f,
- .lineWidth = 1.0f
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+ .depthClampEnable = VK_FALSE,
+ .rasterizerDiscardEnable = VK_FALSE,
+ .polygonMode = VK_POLYGON_MODE_FILL,
+ .cullMode = VK_CULL_MODE_BACK_BIT,
+ .frontFace = VK_FRONT_FACE_CLOCKWISE,
+ .depthBiasEnable = VK_FALSE,
+ .depthBiasConstantFactor = 0.0f,
+ .depthBiasClamp = 0.0f,
+ .depthBiasSlopeFactor = 0.0f,
+ .lineWidth = 1.0f
};
config.multisampleInfo = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
- .sampleShadingEnable = VK_FALSE,
- .minSampleShading = 1.0f,
- .pSampleMask = VK_NULL_HANDLE,
- .alphaToCoverageEnable = VK_FALSE,
- .alphaToOneEnable = VK_FALSE
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+ .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
+ .sampleShadingEnable = VK_FALSE,
+ .minSampleShading = 1.0f,
+ .pSampleMask = VK_NULL_HANDLE,
+ .alphaToCoverageEnable = VK_FALSE,
+ .alphaToOneEnable = VK_FALSE
};
config.colorBlendAttachment = {
- .blendEnable = VK_FALSE,
- .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
- .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
- .colorBlendOp = VK_BLEND_OP_ADD,
- .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
- .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
- .alphaBlendOp = VK_BLEND_OP_ADD,
- .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
- VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
+ .blendEnable = VK_FALSE,
+ .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
+ .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
+ .colorBlendOp = VK_BLEND_OP_ADD,
+ .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
+ .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
+ .alphaBlendOp = VK_BLEND_OP_ADD,
+ .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
+ VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
};
config.depthStencilInfo = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
- .depthTestEnable = VK_TRUE,
- .depthWriteEnable = VK_TRUE,
- .depthCompareOp = VK_COMPARE_OP_LESS,
- .depthBoundsTestEnable = VK_FALSE,
- .stencilTestEnable = VK_FALSE,
- .front = {},
- .back = {},
- .minDepthBounds = 0.0f,
- .maxDepthBounds = 1.0f,
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+ .depthTestEnable = VK_TRUE,
+ .depthWriteEnable = VK_TRUE,
+ .depthCompareOp = VK_COMPARE_OP_LESS,
+ .depthBoundsTestEnable = VK_FALSE,
+ .stencilTestEnable = VK_FALSE,
+ .front = {},
+ .back = {},
+ .minDepthBounds = 0.0f,
+ .maxDepthBounds = 1.0f,
};
}
- Builder &setWidth(const uint32_t w) {
+ Builder& setWidth(const uint32_t w) {
config.viewport.width = static_cast(w);
config.scissor.extent.width = w;
return *this;
}
- Builder &setHeight(const int32_t h) {
+ Builder& setHeight(const int32_t h) {
config.viewport.height = static_cast(-h);
config.viewport.y = static_cast(h);
config.scissor.extent.height = h;
return *this;
}
- Builder &setInputAssembly(VkPipelineInputAssemblyStateCreateInfo info) {
+ Builder& setInputAssembly(VkPipelineInputAssemblyStateCreateInfo info) {
config.inputAssemblyInfo = info;
return *this;
}
- Builder &setRasterization(VkPipelineRasterizationStateCreateInfo info) {
+ Builder& setRasterization(VkPipelineRasterizationStateCreateInfo info) {
config.rasterizationInfo = info;
return *this;
}
- Builder &setMultisample(VkPipelineMultisampleStateCreateInfo info) {
+ Builder& setMultisample(VkPipelineMultisampleStateCreateInfo info) {
config.multisampleInfo = info;
return *this;
}
- Builder &setColorBlend(VkPipelineColorBlendAttachmentState info) {
+ Builder& setColorBlend(VkPipelineColorBlendAttachmentState info) {
config.colorBlendAttachment = info;
return *this;
}
- Builder &setDepthStencil(VkPipelineDepthStencilStateCreateInfo info) {
+ Builder& setDepthStencil(VkPipelineDepthStencilStateCreateInfo info) {
config.depthStencilInfo = info;
return *this;
}
+ Builder& setFormat(const VkFormat format) {
+ config.format = format;
+ return *this;
+ }
+
std::shared_ptr build(
- const std::shared_ptr &d,
- const Swapchain &s,
- const VkShaderProgram &p
+ const std::shared_ptr& d,
+ const VkShaderProgram& p
) {
- return std::make_shared(d, s, p, config);
+ return std::make_shared(d, p, config);
}
};
};
diff --git a/src/engine/vk/VkRenderPass.cpp b/src/engine/vk/VkRenderPass.cpp
index 63b6017..96a1ed9 100644
--- a/src/engine/vk/VkRenderPass.cpp
+++ b/src/engine/vk/VkRenderPass.cpp
@@ -3,12 +3,11 @@
namespace Vixen::Vk {
VkRenderPass::VkRenderPass(
const std::shared_ptr& device,
- const VkShaderProgram& program,
- const Swapchain& swapchain
+ const VkFormat format
) : device(device),
renderPass(VK_NULL_HANDLE) {
attachments.emplace_back(VkAttachmentDescription{
- .format = swapchain.getFormat().format,
+ .format = format,
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
diff --git a/src/engine/vk/VkRenderPass.h b/src/engine/vk/VkRenderPass.h
index d03ebb1..36c7d03 100644
--- a/src/engine/vk/VkRenderPass.h
+++ b/src/engine/vk/VkRenderPass.h
@@ -17,8 +17,7 @@ namespace Vixen::Vk {
public:
VkRenderPass(
const std::shared_ptr &device,
- const VkShaderProgram &program,
- const Swapchain &swapchain
+ VkFormat format
);
VkRenderPass(VkRenderPass& other) = delete;
diff --git a/src/engine/vk/VkRenderer.cpp b/src/engine/vk/VkRenderer.cpp
index bf23261..1b770e3 100644
--- a/src/engine/vk/VkRenderer.cpp
+++ b/src/engine/vk/VkRenderer.cpp
@@ -2,10 +2,9 @@
namespace Vixen::Vk {
VkRenderer::VkRenderer(
- const std::shared_ptr& device,
- Swapchain& swapchain,
- const std::shared_ptr& pipeline
- ) : device(device),
+ const std::shared_ptr& pipeline,
+ const std::shared_ptr& swapchain
+ ) : device(pipeline->getDevice()),
swapchain(swapchain),
pipeline(pipeline),
pipelineLayout(std::make_unique(device, pipeline->getProgram())),
@@ -18,10 +17,10 @@ namespace Vixen::Vk {
renderCommandBuffers(
renderCommandPool->allocate(
VkCommandBuffer::Level::PRIMARY,
- swapchain.getImageCount()
+ swapchain->getImageCount()
)
) {
- const auto imageCount = swapchain.getImageCount();
+ const auto imageCount = swapchain->getImageCount();
renderFinishedSemaphores.reserve(imageCount);
for (size_t i = 0; i < imageCount; i++)
renderFinishedSemaphores.emplace_back(device);
@@ -39,7 +38,7 @@ namespace Vixen::Vk {
uint32_t indexCount,
const std::vector<::VkDescriptorSet>& descriptorSets
) {
- if (const auto state = swapchain.acquireImage(
+ if (const auto state = swapchain->acquireImage(
std::numeric_limits::max(),
[this, &buffer, &vertexCount, &indexCount, &descriptorSets](
const auto& currentFrame,
@@ -62,7 +61,7 @@ namespace Vixen::Vk {
signalSemaphores
);
- swapchain.present(imageIndex, signalSemaphores);
+ swapchain->present(imageIndex, signalSemaphores);
}
); state == Swapchain::State::OUT_OF_DATE) {
device->waitIdle();
@@ -71,7 +70,7 @@ namespace Vixen::Vk {
depthImageViews.clear();
depthImages.clear();
- swapchain.invalidate();
+ swapchain->invalidate();
createFramebuffers();
}
@@ -114,7 +113,7 @@ namespace Vixen::Vk {
.x = 0,
.y = 0
},
- .extent = swapchain.getExtent(),
+ .extent = swapchain->getExtent(),
},
.clearValueCount = static_cast(clearValues.size()),
.pClearValues = clearValues.data()
@@ -127,8 +126,8 @@ namespace Vixen::Vk {
const VkViewport viewport{
.x = 0.0f,
.y = 0.0f,
- .width = static_cast(swapchain.getExtent().width),
- .height = static_cast(swapchain.getExtent().height),
+ .width = static_cast(swapchain->getExtent().width),
+ .height = static_cast(swapchain->getExtent().height),
.minDepth = 0.0f,
.maxDepth = 1.0f,
};
@@ -136,7 +135,7 @@ namespace Vixen::Vk {
const VkRect2D scissor{
.offset = {0, 0},
- .extent = swapchain.getExtent(),
+ .extent = swapchain->getExtent(),
};
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
@@ -180,7 +179,7 @@ namespace Vixen::Vk {
}
void VkRenderer::createFramebuffers() {
- const auto& imageCount = swapchain.getImageCount();
+ const auto& imageCount = swapchain->getImageCount();
depthImages.reserve(imageCount);
depthImageViews.reserve(imageCount);
@@ -189,8 +188,8 @@ namespace Vixen::Vk {
depthImages.push_back(
std::make_shared(
device,
- swapchain.getExtent().width,
- swapchain.getExtent().height,
+ swapchain->getExtent().width,
+ swapchain->getExtent().height,
VK_SAMPLE_COUNT_1_BIT,
VK_FORMAT_D32_SFLOAT,
VK_IMAGE_TILING_OPTIMAL,
@@ -209,10 +208,10 @@ namespace Vixen::Vk {
framebuffers.emplace_back(
device,
pipeline->getRenderPass(),
- swapchain.getExtent().width,
- swapchain.getExtent().height,
+ swapchain->getExtent().width,
+ swapchain->getExtent().height,
std::vector{
- swapchain.getImageViews()[i],
+ swapchain->getImageViews()[i],
depthImageViews[i]->getImageView()
}
);
diff --git a/src/engine/vk/VkRenderer.h b/src/engine/vk/VkRenderer.h
index 630143f..5d6f066 100644
--- a/src/engine/vk/VkRenderer.h
+++ b/src/engine/vk/VkRenderer.h
@@ -12,7 +12,7 @@ namespace Vixen::Vk {
class VkRenderer {
std::shared_ptr device;
- Swapchain& swapchain;
+ std::shared_ptr swapchain;
std::unique_ptr pipelineLayout;
@@ -32,9 +32,8 @@ namespace Vixen::Vk {
public:
VkRenderer(
- const std::shared_ptr& device,
- Swapchain& swapchain,
- const std::shared_ptr& pipeline
+ const std::shared_ptr& pipeline,
+ const std::shared_ptr& swapchain
);
VkRenderer(const VkRenderer&) = delete;
diff --git a/src/engine/vk/VkVixen.cpp b/src/engine/vk/VkVixen.cpp
index b96f115..51ce45c 100644
--- a/src/engine/vk/VkVixen.cpp
+++ b/src/engine/vk/VkVixen.cpp
@@ -1,19 +1,31 @@
#include "VkVixen.h"
namespace Vixen::Vk {
- VkVixen::VkVixen(const std::string &appTitle, glm::vec3 appVersion)
- : Vixen(appTitle, appVersion),
- window(VkWindow(appTitle, 640, 480, false)),
- instance(Instance(appTitle, appVersion, window.requiredExtensions)),
- surface(instance.surfaceForWindow(window)),
- device(std::make_shared(
- instance,
- deviceExtensions,
- instance.findOptimalGraphicsCard(surface, deviceExtensions),
- surface
- )),
- swapchain(device, 3) {
- window.center();
- window.setVisible(true);
+ VkVixen::VkVixen(const std::string& appTitle, glm::vec3 appVersion)
+ : Vixen(appTitle, appVersion),
+ window(std::make_unique(appTitle, 640, 480, false)),
+ instance(Instance(appTitle, appVersion, window->getRequiredExtensions())),
+ surface(instance.surfaceForWindow(*window)),
+ device(std::make_shared(
+ instance,
+ deviceExtensions,
+ instance.findOptimalGraphicsCard(surface, deviceExtensions),
+ surface
+ )),
+ swapchain(std::make_shared(device, 3)) {
+ window->center();
+ window->setVisible(true);
}
+
+ std::vector VkVixen::getDeviceExtensions() const { return deviceExtensions; }
+
+ std::shared_ptr VkVixen::getWindow() const { return window; }
+
+ Instance VkVixen::getInstance() const { return instance; }
+
+ VkSurfaceKHR VkVixen::getSurface() const { return surface; }
+
+ std::shared_ptr VkVixen::getDevice() const { return device; }
+
+ std::shared_ptr VkVixen::getSwapchain() const { return swapchain; }
}
diff --git a/src/engine/vk/VkVixen.h b/src/engine/vk/VkVixen.h
index c4d0ea8..760dc79 100644
--- a/src/engine/vk/VkVixen.h
+++ b/src/engine/vk/VkVixen.h
@@ -9,12 +9,11 @@
namespace Vixen::Vk {
class VkVixen : public Vixen {
- public:
- const std::vector deviceExtensions = {
- VK_KHR_SWAPCHAIN_EXTENSION_NAME
+ const std::vector deviceExtensions = {
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
- VkWindow window;
+ std::shared_ptr window;
Instance instance;
@@ -22,12 +21,25 @@ namespace Vixen::Vk {
std::shared_ptr device;
- Swapchain swapchain;
+ std::shared_ptr swapchain;
+
+ public:
+ VkVixen(const std::string& appTitle, glm::vec3 appVersion);
+
+ VkVixen(const VkVixen&) = delete;
+
+ VkVixen& operator=(const VkVixen&) = delete;
+
+ [[nodiscard]] std::vector getDeviceExtensions() const;
+
+ [[nodiscard]] std::shared_ptr getWindow() const;
+
+ [[nodiscard]] Instance getInstance() const;
- VkVixen(const std::string &appTitle, glm::vec3 appVersion);
+ [[nodiscard]] VkSurfaceKHR getSurface() const;
- VkVixen(const VkVixen &) = delete;
+ [[nodiscard]] std::shared_ptr getDevice() const;
- VkVixen &operator=(const VkVixen &) = delete;
+ [[nodiscard]] std::shared_ptr getSwapchain() const;
};
}
diff --git a/src/engine/vk/VkWindow.cpp b/src/engine/vk/VkWindow.cpp
index c22413c..140fda4 100644
--- a/src/engine/vk/VkWindow.cpp
+++ b/src/engine/vk/VkWindow.cpp
@@ -5,12 +5,10 @@ namespace Vixen::Vk {
const std::string &title,
const uint32_t &width,
const uint32_t &height,
- bool transparentFrameBuffer
- ) : Vixen::Window(title, width, height, transparentFrameBuffer) {
+ const bool transparentFrameBuffer
+ ) : Window(title, width, height, transparentFrameBuffer) {
spdlog::trace("Creating new Vulkan window");
if (!glfwVulkanSupported()) {
- glfwDestroyWindow(window);
- glfwTerminate();
spdlog::error("Vulkan is not supported on this device");
throw std::runtime_error("Vulkan is not supported on this device");
}
@@ -28,9 +26,11 @@ namespace Vixen::Vk {
VkSurfaceKHR VkWindow::createSurface(VkInstance instance) const {
VkSurfaceKHR surface = VK_NULL_HANDLE;
checkVulkanResult(
- glfwCreateWindowSurface(instance, window, nullptr, &surface),
+ glfwCreateWindowSurface(instance, getWindow(), nullptr, &surface),
"Failed to create Vulkan BaseWindow surface"
);
return surface;
}
+
+ std::vector VkWindow::getRequiredExtensions() const { return requiredExtensions; }
}
diff --git a/src/engine/vk/VkWindow.h b/src/engine/vk/VkWindow.h
index b582205..455d3ce 100644
--- a/src/engine/vk/VkWindow.h
+++ b/src/engine/vk/VkWindow.h
@@ -1,23 +1,24 @@
#pragma once
-#include
-#include "../Window.h"
#include "Vulkan.h"
+#include "../Window.h"
namespace Vixen::Vk {
class VkWindow : public Window {
std::vector images;
- public:
- std::vector requiredExtensions;
+ std::vector requiredExtensions;
+ public:
VkWindow(
- const std::string &title,
- const uint32_t &width,
- const uint32_t &height,
- bool transparentFrameBuffer
+ const std::string& title,
+ const uint32_t& width,
+ const uint32_t& height,
+ bool transparentFrameBuffer
);
VkSurfaceKHR createSurface(VkInstance instance) const;
+
+ [[nodiscard]] std::vector getRequiredExtensions() const;
};
}
diff --git a/src/engine/vk/test/main.cpp b/src/engine/vk/test/main.cpp
index 07d7d0f..4af9ac0 100644
--- a/src/engine/vk/test/main.cpp
+++ b/src/engine/vk/test/main.cpp
@@ -63,21 +63,22 @@ int main() {
.size = sizeof(glm::vec2),
.offset = offsetof(Vertex, uv)
})
- .compileFromFile(vixen.device, "../../src/editor/shaders/triangle.vert");
+ .compileFromFile(vixen.getDevice(), "../../src/editor/shaders/triangle.vert");
const auto fragment = Vixen::Vk::VkShaderModule::Builder(Vixen::ShaderModule::Stage::FRAGMENT)
- .compileFromFile(vixen.device, "../../src/editor/shaders/triangle.frag");
+ .compileFromFile(vixen.getDevice(), "../../src/editor/shaders/triangle.frag");
const auto program = Vixen::Vk::VkShaderProgram(vertexShader, fragment);
int width;
int height;
- vixen.window.getFramebufferSize(width, height);
+ vixen.getWindow()->getFramebufferSize(width, height);
auto pipeline = Vixen::Vk::VkPipeline::Builder()
.setWidth(width)
.setHeight(height)
- .build(vixen.device, vixen.swapchain, program);
+ .setFormat(vixen.getSwapchain()->getFormat().format)
+ .build(vixen.getDevice(), program);
- auto renderer = std::make_unique(vixen.device, vixen.swapchain, pipeline);
+ auto renderer = std::make_unique(pipeline, vixen.getSwapchain());
Assimp::Importer importer;
const auto& scene = importer.ReadFile("../../src/engine/vk/test/vikingroom.glb",
@@ -124,12 +125,13 @@ int main() {
std::shared_ptr image;
if (texture->mHeight != 0) {
- image = nullptr; // TODO
+ // TODO: Not implemented
+ throw std::runtime_error("Not implemented");
}
else {
image = std::make_shared(
Vixen::Vk::VkImage::from(
- vixen.device,
+ vixen.getDevice(),
texture->achFormatHint,
reinterpret_cast(texture->pcData),
texture->mWidth
@@ -138,7 +140,7 @@ int main() {
}
const auto buffer = Vixen::Vk::VkBuffer::stage(
- vixen.device,
+ vixen.getDevice(),
Vixen::Buffer::Usage::VERTEX |
Vixen::Buffer::Usage::INDEX,
vertices.size() * sizeof(Vertex) +
@@ -158,7 +160,7 @@ int main() {
}
);
- auto camera = Vixen::Camera(glm::vec3{1.0f, 1.0f, 1.0f});
+ auto camera = Vixen::Camera(glm::vec3{0.0f, 0.0f, 0.0f});
const std::vector sizes{
{
@@ -172,27 +174,27 @@ int main() {
};
auto uniformBuffer = Vixen::Vk::VkBuffer(
- vixen.device,
+ vixen.getDevice(),
Vixen::Buffer::Usage::UNIFORM,
sizeof(UniformBufferObject)
);
UniformBufferObject ubo{
- glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
+ glm::mat4(1.0f),
camera.view(),
camera.perspective(static_cast(width) / static_cast(height))
};
+ ubo.model = translate(ubo.model, {0.0f, -0.5f, -1.5f});
+ //ubo.model = rotate(ubo.model, glm::radians(45.0f), {1.0f, 0.0f, 1.0f});
+ ubo.model = rotate(ubo.model, glm::radians(225.0f), {0.0f, 1.0f, 0.0f});
+ //ubo.model = rotate(ubo.model, glm::radians(45.0f), {0.0f, 0.0f, 1.0f});
- auto descriptorPool = std::make_shared(vixen.device, sizes, 1);
- auto mvp = Vixen::Vk::VkDescriptorSet(vixen.device, descriptorPool, *program.getDescriptorSetLayout());
+ auto descriptorPool = std::make_shared(vixen.getDevice(), sizes, 1);
+ auto mvp = Vixen::Vk::VkDescriptorSet(vixen.getDevice(), descriptorPool, *program.getDescriptorSetLayout());
mvp.updateUniformBuffer(0, uniformBuffer, 0, uniformBuffer.getSize());
- auto testImage = std::make_shared(
- Vixen::Vk::VkImage::from(vixen.device, std::string("../../src/engine/vk/test/texture.jpg")));
auto view = Vixen::Vk::VkImageView(image, VK_IMAGE_ASPECT_COLOR_BIT);
- auto sampler = Vixen::Vk::VkSampler(vixen.device);
-
- //auto albedo = Vixen::Vk::VkDescriptorSet(vixen.device, descriptorPool, *program.getDescriptorSetLayout());
+ auto sampler = Vixen::Vk::VkSampler(vixen.getDevice());
mvp.updateCombinedImageSampler(1, sampler, view);
const std::vector descriptorSets = {mvp.getSet()};
@@ -200,22 +202,21 @@ int main() {
double old = glfwGetTime();
double lastFrame = old;
uint32_t fps = 0;
- while (!vixen.window.shouldClose()) {
- if (vixen.window.update()) {
- vixen.swapchain.invalidate();
+ while (!vixen.getWindow()->shouldClose()) {
+ if (vixen.getWindow()->update()) {
+ vixen.getSwapchain()->invalidate();
// TODO: Recreating the entire renderer is probably overkill, need a better way to recreate framebuffers on resize triggered from window
- renderer = std::make_unique(vixen.device, vixen.swapchain, pipeline);
+ renderer = std::make_unique(pipeline, vixen.getSwapchain());
}
const double& now = glfwGetTime();
double deltaTime = now - lastFrame;
lastFrame = now;
- ubo.model = rotate(glm::mat4(1.0f), /*static_cast(deltaTime) **/ glm::radians(90.0f),
- glm::vec3(1.0f, 0.0f, 0.0f));
ubo.view = camera.view();
+ const auto& extent = vixen.getSwapchain()->getExtent();
ubo.projection = camera.perspective(
- static_cast(vixen.swapchain.getExtent().width) /
- static_cast(vixen.swapchain.getExtent().height)
+ static_cast(extent.width) /
+ static_cast(extent.height)
);
uniformBuffer.write(reinterpret_cast(&ubo), sizeof(UniformBufferObject), 0);
@@ -229,7 +230,7 @@ int main() {
}
}
- vixen.device->waitIdle();
+ vixen.getDevice()->waitIdle();
return EXIT_SUCCESS;
}