diff --git a/.idea/editor.xml b/.idea/editor.xml
index 8d0e15e..33921db 100644
--- a/.idea/editor.xml
+++ b/.idea/editor.xml
@@ -246,100 +246,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8a6ef01..44cfed9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,7 +75,7 @@ target_include_directories(v
${CMAKE_CURRENT_SOURCE_DIR}
)
-target_link_libraries(v PRIVATE glfw Vulkan::Vulkan glm stb slang_sdk)
+target_link_libraries(v PRIVATE glfw Vulkan::Vulkan glm::glm stb slang_sdk)
set(SHADER_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/shaders")
set(SHADER_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders")
diff --git a/main.cpp b/main.cpp
index 7098185..af79f6e 100644
--- a/main.cpp
+++ b/main.cpp
@@ -18,14 +18,24 @@
GLFWwindow *window;
-int main() {
- std::print("Hello, Sailor!");
+int32_t window_width = 640;
+int32_t window_height = 480;
+uint64_t t = 0;
+uint64_t accumulator = 0;
+
+uint64_t dt = 0;
+
+int main() {
if (!glfwInit())
return -1;
+ dt = (uint64_t) (1.0 / 60.0 * glfwGetTimerFrequency());
+
+ std::println("Hello, Sailor!");
+
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
- window = glfwCreateWindow(640, 480, "Hello World", nullptr, nullptr);
+ window = glfwCreateWindow(window_width, window_height, "Hello World", nullptr, nullptr);
if (!window) {
glfwTerminate();
return -1;
@@ -43,19 +53,45 @@ int main() {
texture_manager.load("assets/boy.jpg", renderer);
+ uint64_t current_time = glfwGetTimerValue();
+
while (!glfwWindowShouldClose(window)) {
+ uint64_t new_time = glfwGetTimerValue();
+ uint64_t frame_time = new_time - current_time;
+ current_time = new_time;
+
+ accumulator += frame_time;
+
glfwPollEvents();
+ uint64_t updates = 0;
+
+ while (accumulator >= dt) {
+ accumulator -= dt;
+ t += dt;
+ updates++;
+ }
+ std::println("Updates: {}", updates);
+ std::println("frame time: {}", ((double) (frame_time) / (double) glfwGetTimerFrequency()));
+
renderer.begin_frame();
- renderer.submit_quad({-0.5, 0.0});
+ double f = 15.0 * (t / (double) glfwGetTimerFrequency());
- renderer.submit_quad({0.5, 0.0});
+ renderer.submit_quad(
+ {
+ 100.0 + 10.0 * glm::sin(f),
+ 100.0 - 10.0 * glm::cos(f),
+ },
+ {100.0, 100.0});
+
+ renderer.submit_quad({400.0, 400.0}, {20.0, 20.0});
// renderer.submit_sprite();
renderer.end_frame();
+
}
vkDeviceWaitIdle(device);
diff --git a/renderer/renderer.cpp b/renderer/renderer.cpp
index 2a857f9..1b7ea49 100644
--- a/renderer/renderer.cpp
+++ b/renderer/renderer.cpp
@@ -3,11 +3,17 @@
//
#include "renderer.h"
+
+#include
+
#include "init.h"
#include "sprite.h"
#include
#include
+extern int32_t window_width;
+extern int32_t window_height;
+
bool SortKey::operator<(const SortKey& b) const {
if (depth != b.depth) return depth < b.depth;
if (pipeline != b.pipeline) return pipeline < b.pipeline;
@@ -37,7 +43,7 @@ void Renderer::flush() {
}
-void Renderer::submit_quad(glm::vec2 pos) {
+void Renderer::submit_quad(glm::vec2 pos, glm::vec2 scale) {
RenderCommand cmd {};
cmd.pipeline = PipelineType::ColoredQuad;
cmd.key = {
@@ -48,7 +54,7 @@ void Renderer::submit_quad(glm::vec2 pos) {
cmd.colored_quad = {
.pos = pos,
- .scale = {0.25, 0.25},
+ .scale = scale,
.color = {0, 1, 1, 1},
};
@@ -133,11 +139,10 @@ void Renderer::create_pipeline_layout() {
vkCreateDescriptorSetLayout(device, &dslci, nullptr, &descriptor_set_layout);
- // 2. Create the Shared Pipeline Layout
VkPushConstantRange push_constant{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = 0,
- .size = sizeof(glm::mat4) // Camera Projection
+ .size = sizeof(glm::mat4),
};
VkPipelineLayoutCreateInfo plci{
@@ -574,7 +579,7 @@ void Renderer::end_frame() {
// float v1 = q.uvMax.y;
// Define the 4 corners of the quad
- vertex_p2_s2_st2_col4_a1_u32 vTL = { q.pos, q.scale, {0, 0}, q.color, 1, 0 };
+ vertex_p2_s2_st2_col4_a1_u32 vTL = { q.pos, q.scale, {0, 0}, {1, 0, 0, 0}, 1, 0 };
vertex_p2_s2_st2_col4_a1_u32 vTR = { q.pos, q.scale, {0, 0}, q.color, 1, 0 };
vertex_p2_s2_st2_col4_a1_u32 vBL = { q.pos, q.scale, {0, 0}, q.color, 1, 0 };
vertex_p2_s2_st2_col4_a1_u32 vBR = { q.pos, q.scale, {0, 0}, q.color, 1, 0 };
@@ -709,7 +714,7 @@ void Renderer::recordCommandBuffer(
toColor.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
toColor.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
toColor.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
- toColor.oldLayout = oldLayout;
+ toColor.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
toColor.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
toColor.image = image;
toColor.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
@@ -753,6 +758,17 @@ void Renderer::recordCommandBuffer(
VkDeviceSize vOffset{ 0 };
vkCmdBindVertexBuffers(cmd, 0, 1, &frame.vertexBuffer.buffer, &vOffset);
+ glm::mat4 projection = glm::ortho(0.0f, (float)window_width, 0.0f, (float)window_height, -1.0f, 1.0f);
+
+ vkCmdPushConstants(
+ cmd,
+ pipelineLayout,
+ VK_SHADER_STAGE_VERTEX_BIT,
+ 0,
+ sizeof(glm::mat4),
+ &projection
+ );
+
PipelineType lastPipeline = PipelineType::None; // Track current state
// uint32_t vertexOffset = currentFrame * MAX_VERTICES_PER_BATCH;
uint32_t currentBatchVertices = 0;
@@ -783,16 +799,24 @@ void Renderer::recordCommandBuffer(
// 3. Transition back to Present
{
- VkImageMemoryBarrier2 toPresent{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 };
- toPresent.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
- toPresent.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
- toPresent.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
- toPresent.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- toPresent.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
- toPresent.image = image;
- toPresent.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+ VkImageMemoryBarrier2 toPresent{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
+ .srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .dstAccessMask = 0,
+ .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ .image = image,
+ .subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 },
+ };
- VkDependencyInfo dep{ .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, .imageMemoryBarrierCount = 1, .pImageMemoryBarriers = &toPresent };
+ VkDependencyInfo dep{
+ .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
+ .imageMemoryBarrierCount = 1,
+ .pImageMemoryBarriers = &toPresent
+ };
+
vkCmdPipelineBarrier2(cmd, &dep);
}
diff --git a/renderer/renderer.h b/renderer/renderer.h
index cd2036d..1d4a46d 100644
--- a/renderer/renderer.h
+++ b/renderer/renderer.h
@@ -8,7 +8,12 @@
#include "init.h"
#include
#include
+#define GLM_FORCE_RADIANS
+#define GLM_FORCE_DEPTH_ZERO_TO_ONE
+#define GLM_ENABLE_EXPERIMENTAL
#include
+#include
+#include "glm/gtx/string_cast.hpp"
#include
#include "sprite.h"
#include "texture.h"
@@ -173,7 +178,7 @@ struct Renderer {
void flush();
void submit_sprite(glm::vec2 pos, const sprite_t &sprite);
- void submit_quad(glm::vec2 pos);
+ void submit_quad(glm::vec2 pos, glm::vec2 scale);
explicit Renderer(GLFWwindow *window);
void create_pipeline_layout();
diff --git a/shaders/shader.slang b/shaders/shader.slang
index 0b8b06a..b06c2e1 100644
--- a/shaders/shader.slang
+++ b/shaders/shader.slang
@@ -5,6 +5,8 @@ struct VSInput {
float4 color;
float alpha;
uint32_t textureID;
+
+ uint vertex_index : SV_VertexID;
};
struct VSOutput {
@@ -26,13 +28,13 @@ static const float2 square[6] = {
};
[shader ("vertex")]
-VSOutput main(VSInput input, uint vertex_index : SV_VertexID) {
+VSOutput main(VSInput input, uniform float4x4 proj) {
VSOutput output;
- float2 vertex_pos = square[vertex_index % 6];
+ float2 vertex_pos = square[input.vertex_index % 6];
float2 final_pos = (vertex_pos * input.scale) + input.pos;
- output.pos = float4(final_pos, 0.0, 1.0);
+ output.pos = mul(proj, float4(final_pos, 0.0, 1.0));
output.uv = input.uv;
output.color = input.color;
output.alpha = input.alpha;