Compare commits

..

1 commit
main ... 3d

Author SHA1 Message Date
5161bb75ba 3d cube more or less working 2025-06-04 21:39:15 +02:00
5 changed files with 163 additions and 241 deletions

View file

@ -1,3 +0,0 @@
This is a prototype for a game engine im doing, its very messy and imperfect, but its a working vulkan renderer (and an small minigame that doesnt work yet) made in c++23 that works in basically any system that supports vulkan (with some changes to the CMakeLists.txt file)
I'm learning while writing this so expect some bad practices and weird stuff!

387
main.cpp
View file

@ -1,3 +1,5 @@
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <print> #include <print>
@ -5,14 +7,11 @@
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <atomic> #include <atomic>
#include <thread> #include <thread>
#include <random>
bool skip_rendering = false; bool skip_rendering = false;
bool stop_physics = false;
std::atomic_bool pressed_space = false;
std::atomic_bool pressed_shift = false;
vk::SurfaceFormatKHR format; vk::SurfaceFormatKHR format;
vk::Extent2D framebuffer_extension; vk::Extent2D framebuffer_extension;
@ -24,37 +23,25 @@ struct vertex
glm::vec3 color; glm::vec3 color;
}; };
struct vertex_3d
{
glm::vec3 position;
glm::vec3 color;
};
struct bounding_box struct bounding_box
{ {
float x; float x;
float y; float y;
float width; float width;
float height; float height;
float velocityX;
float velocityY;
float accX;
float accY;
}; };
struct uniform struct uniform
{
glm::mat4 view;
};
struct push
{ {
glm::mat4 transform; glm::mat4 transform;
}; };
struct quad
{
bounding_box box;
std::vector<vertex> vertices;
push trans;
};
bounding_box player; bounding_box player;
float velocityX = 1.0f; float velocityX = 1.0f;
float velocityY = 0.50f; float velocityY = 0.50f;
@ -183,6 +170,16 @@ std::vector<vertex> convert_quad_to_triangles(std::vector<vertex> vertices)
return vertices; return vertices;
} }
std::vector<vertex_3d> convert_quad_to_triangles(std::vector<vertex_3d> vertices)
{
const vertex_3d end_vertex = vertices[3];
vertices.pop_back();
vertices.push_back(vertices[0]);
vertices.push_back(vertices[2]);
vertices.push_back(end_vertex);
return vertices;
}
glm::mat4 rotate(float angle) glm::mat4 rotate(float angle)
{ {
float c = glm::cos(glm::radians(angle)); float c = glm::cos(glm::radians(angle));
@ -219,53 +216,16 @@ void simple_physics()
} }
} }
bool simple_physics_step(float t, bounding_box &box, std::vector<quad> &boxes, bool &on_ground) void simple_physics_step(float t)
{ {
box.y += box.velocityY * t + 0.5 * box.accY * (t * t); bool collision_x = player.x + player.width / 2 >= 1.0f || player.x - player.width / 2 <= -1.0f;
box.velocityY += box.accY * t; bool collision_y = player.y + player.height / 2 >=1.0f || player.y - player.height / 2 <= -1.0f;
box.x += box.velocityX * t + 0.5 * box.accX * (t * t);
box.velocityX += box.accX * t;
bool end_game = false;
for (auto &b: boxes)
{
b.box.y += b.box.velocityY * t + 0.5 * b.box.accY * (t * t);
b.box.velocityY += b.box.accY * t;
b.box.x += b.box.velocityX * t + 0.5 * b.box.accX * (t * t);
b.box.velocityX += b.box.accX * t;
bool collision_x = b.box.x + b.box.width / 2 >= box.x - box.width /2 && b.box.x - b.box.width / 2 <= box.x + box.width /2;
bool collision_y = b.box.y + b.box.height / 2 >= box.y - box.height /2 && b.box.y - b.box.height / 2 <= box.y + box.height /2;
end_game = collision_x && collision_y;
if (end_game)
{
#ifdef NDEBUG
std::println("Collision between pos x: {} y: {} and pos x: {} and pos y: {} ", box.x, box.y, b.box.x, b.box.y);
std::println("With width: {} and height: {} and width: {} and height: {}", box.width, box.height, b.box.width, b.box.height);
std::println("Rightmost vertex in position {} collided with leftmost vertex in position {}", box.x + box.width/2, b.box.x - b.box.width/2);
#endif
}
}
bool collision_x = box.x + box.width / 2 >= 1.0f || box.x - box.width / 2 <= -1.0f;
bool collision_top_y = box.y - box.height / 2 <= -1.0f;
bool collision_bottom_y = box.y + box.height / 2 >=1.0f;
if (collision_x) if (collision_x)
box.velocityX = 0; velocityX = -velocityX;
else if (collision_top_y) else if (collision_y)
{ velocityY = -velocityY;
box.velocityY = 0; player.x = player.x + (velocityX * t);
box.y = -1.0f + box.height/2; player.y = player.y + (velocityY * t);
}
else if (collision_bottom_y)
{
box.velocityY = 0.0f;
box.y = 1.0f - box.height/2;
on_ground = true;
}
return end_game;
} }
std::pair<vk::DeviceMemory, vk::Buffer> create_buffer(const vk::Device &device, vk::PhysicalDevice selected_physical_device, vk::BufferUsageFlagBits usage, size_t size) std::pair<vk::DeviceMemory, vk::Buffer> create_buffer(const vk::Device &device, vk::PhysicalDevice selected_physical_device, vk::BufferUsageFlagBits usage, size_t size)
@ -297,66 +257,59 @@ std::pair<vk::DeviceMemory, vk::Buffer> create_buffer(const vk::Device &device,
return std::make_pair(vertex_buffer_memory, vertex_buffer); return std::make_pair(vertex_buffer_memory, vertex_buffer);
} }
void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int mods) std::pair<vk::DeviceMemory, vk::Image> create_image(vk::Device &device, size_t width, size_t height, size_t depth, vk::Format format, vk::ImageUsageFlags usage)
{ {
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) vk::Extent3D extent(width, height, depth);
{ vk::ImageCreateInfo image_create_info(vk::ImageCreateFlags(), vk::ImageType::e2D, format, extent, 1,
//std::println("JUMP!"); 1, vk::SampleCountFlagBits::e1, vk::ImageTiling::eOptimal,
pressed_space = true; usage);
} vk::Image image = device.createImage(image_create_info);
else if (key == GLFW_KEY_LEFT_SHIFT && action == GLFW_PRESS)
{ vk::MemoryRequirements memory_requirements;
pressed_shift = true; device.getImageMemoryRequirements(image, &memory_requirements);
} vk::MemoryAllocateInfo memory_allocate_info(memory_requirements.size, 0x0);
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) vk::DeviceMemory memory = device.allocateMemory(memory_allocate_info, nullptr);
exit(0); device.bindImageMemory(image, memory, 0);
return std::make_pair(memory, image);
} }
bounding_box spawn_enemy(std::mt19937 rng) vk::ImageView create_image_view(vk::Device &device, vk::Image image, vk::Format format, vk::ImageAspectFlagBits aspect)
{ {
std::uniform_real_distribution<float> dist(0.05, 0.4); vk::ImageViewCreateInfo image_view_info = {};
std::uniform_real_distribution<float> y_dist(0.6, 0.9); image_view_info.image = image;
std::uniform_real_distribution<float> vel_dist(-1.5, -0.5); image_view_info.viewType = vk::ImageViewType::e2D;
bounding_box ret{0}; image_view_info.format = format;
ret.height = dist(rng); image_view_info.components.r = vk::ComponentSwizzle::eIdentity;
ret.width = dist(rng); image_view_info.components.g = vk::ComponentSwizzle::eIdentity;
ret.x = 0.8; image_view_info.components.b = vk::ComponentSwizzle::eIdentity;
ret.y = y_dist(rng); image_view_info.components.a = vk::ComponentSwizzle::eIdentity;
ret.velocityX = vel_dist(rng); image_view_info.subresourceRange.aspectMask = aspect;
return ret; image_view_info.subresourceRange.baseMipLevel = 0;
image_view_info.subresourceRange.levelCount = 1;
image_view_info.subresourceRange.baseArrayLayer = 0;
image_view_info.subresourceRange.layerCount = 1;
return device.createImageView(image_view_info);
} }
void add_quad_to_vertices(std::vector<vertex> &vertices, std::vector<vertex> new_quad) void add_quad_to_vertices(std::vector<vertex_3d> &vertices, std::vector<vertex_3d> new_quad)
{ {
new_quad = convert_quad_to_triangles(new_quad); new_quad = convert_quad_to_triangles(new_quad);
for (auto vert: new_quad) for (auto vert: new_quad)
{ {
//std::println("Vertex pos x: {}, y: {}, z: {}", vert.position.x, vert.position.y, vert.position.z); std::println("Vertex pos x: {}, y: {}, z: {}", vert.position.x, vert.position.y, vert.position.z);
vertices.push_back(vert); vertices.push_back(vert);
} }
} }
std::vector<vertex> bounding_box_to_vertices(const bounding_box &box)
{
float half_width = box.width/2;
float half_height = box.height/2;
std::vector<vertex> vertices = {
{{-half_width, -half_height}, {1.0f, 0.0f, 0.0f}},
{{half_width, -half_height}, {1.0f, 0.0f, 0.0f}},
{{half_width, half_height}, {0.0f, 1.0f, 0.0f}},
{{-half_width, half_height}, {0.0f, 0.0f, 1.0f}}
};
return vertices;
}
int main() int main()
{ {
using clock = std::chrono::system_clock; using clock = std::chrono::system_clock;
using ms = std::chrono::duration<double, std::milli>; using ms = std::chrono::duration<double, std::milli>;
GLFWwindow *window = create_window(1000, 800, "hello"); GLFWwindow *window = create_window(1000, 800, "hello");
std::random_device dev;
std::mt19937 rng(dev());
if (!window) if (!window)
return -1; return -1;
@ -382,12 +335,7 @@ int main()
#endif #endif
vk::InstanceCreateInfo createinfo = vk::InstanceCreateInfo( vk::InstanceCreateInfo createinfo = vk::InstanceCreateInfo(
#ifdef __APPLE__
vk::InstanceCreateFlags(VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR), vk::InstanceCreateFlags(VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR),
#endif
#ifdef __linux__
vk::InstanceCreateFlags(),
#endif
&appinfo,layers.size(), layers.data(), &appinfo,layers.size(), layers.data(),
extensions.size(), extensions.data()); extensions.size(), extensions.data());
vk::Instance instance = vk::createInstance(createinfo); vk::Instance instance = vk::createInstance(createinfo);
@ -493,20 +441,20 @@ int main()
vk::VertexInputBindingDescription binding_description = {}; vk::VertexInputBindingDescription binding_description = {};
binding_description.binding = 0; binding_description.binding = 0;
binding_description.stride = sizeof(vertex); binding_description.stride = sizeof(vertex_3d);
binding_description.inputRate = vk::VertexInputRate::eVertex; binding_description.inputRate = vk::VertexInputRate::eVertex;
vk::VertexInputAttributeDescription att_description_pos = {}; vk::VertexInputAttributeDescription att_description_pos = {};
att_description_pos.binding = 0; att_description_pos.binding = 0;
att_description_pos.location = 0; att_description_pos.location = 0;
att_description_pos.format = vk::Format::eR32G32Sfloat; att_description_pos.format = vk::Format::eR32G32B32Sfloat;
att_description_pos.offset = offsetof(vertex, position); att_description_pos.offset = offsetof(vertex_3d, position);
vk::VertexInputAttributeDescription att_description_color = {}; vk::VertexInputAttributeDescription att_description_color = {};
att_description_color.binding = 0; att_description_color.binding = 0;
att_description_color.location = 1; att_description_color.location = 1;
att_description_color.format = vk::Format::eR32G32B32Sfloat; att_description_color.format = vk::Format::eR32G32B32Sfloat;
att_description_color.offset = offsetof(vertex, color); att_description_color.offset = offsetof(vertex_3d, color);
std::vector<vk::VertexInputAttributeDescription> att_descriptions = {att_description_pos, att_description_color}; std::vector<vk::VertexInputAttributeDescription> att_descriptions = {att_description_pos, att_description_color};
vk::PipelineVertexInputStateCreateInfo vertex_input_info = {}; vk::PipelineVertexInputStateCreateInfo vertex_input_info = {};
@ -555,17 +503,13 @@ int main()
vk::DescriptorSetLayoutCreateInfo descriptor_layout_info(vk::DescriptorSetLayoutCreateFlags(), 1, &descriptor_binding); vk::DescriptorSetLayoutCreateInfo descriptor_layout_info(vk::DescriptorSetLayoutCreateFlags(), 1, &descriptor_binding);
vk::DescriptorSetLayout descriptor_layout = device.createDescriptorSetLayout(descriptor_layout_info); vk::DescriptorSetLayout descriptor_layout = device.createDescriptorSetLayout(descriptor_layout_info);
vk::PushConstantRange push_constant(vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push));
vk::PipelineLayoutCreateInfo layout_info = {}; vk::PipelineLayoutCreateInfo layout_info = {};
layout_info.setLayoutCount = 1; layout_info.setLayoutCount = 1;
layout_info.pSetLayouts = &descriptor_layout; layout_info.pSetLayouts = &descriptor_layout;
layout_info.pushConstantRangeCount = 1;
layout_info.pPushConstantRanges = &push_constant;
vk::PipelineLayout pipeline_layout = device.createPipelineLayout(layout_info); vk::PipelineLayout pipeline_layout = device.createPipelineLayout(layout_info);
uniform u{}; uniform u{};
u.view = glm::mat4(1.0f); u.transform = glm::mat4{1.0f};
auto rec = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eUniformBuffer, sizeof(uniform)); auto rec = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eUniformBuffer, sizeof(uniform));
vk::DeviceMemory uniform_buffer_data = rec.first; vk::DeviceMemory uniform_buffer_data = rec.first;
vk::Buffer uniform_buffer = rec.second; vk::Buffer uniform_buffer = rec.second;
@ -578,21 +522,34 @@ int main()
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR); vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR);
vk::AttachmentReference attachment_ref = vk::AttachmentReference(0, vk::ImageLayout::eColorAttachmentOptimal); vk::AttachmentReference attachment_ref = vk::AttachmentReference(0, vk::ImageLayout::eColorAttachmentOptimal);
auto image_ret = create_image(device, framebuffer_extension.width, framebuffer_extension.height, 1,vk::Format::eD32Sfloat, vk::ImageUsageFlags(vk::ImageUsageFlagBits::eDepthStencilAttachment));
vk::Image depth_image = image_ret.second;
vk::DeviceMemory depht_image_memory = image_ret.first;
vk::ImageView depth_image_view = create_image_view(device, depth_image, vk::Format::eD32Sfloat, vk::ImageAspectFlagBits::eDepth);
vk::AttachmentDescription depth_attachment_desc(vk::AttachmentDescriptionFlags(), vk::Format::eD32Sfloat,
vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare,
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined,
vk::ImageLayout::eDepthStencilAttachmentOptimal);
vk::AttachmentReference depth_attachment_ref(1, vk::ImageLayout::eDepthStencilAttachmentOptimal);
vk::SubpassDescription subpass_description = {}; vk::SubpassDescription subpass_description = {};
subpass_description.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; subpass_description.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
subpass_description.colorAttachmentCount = 1; subpass_description.colorAttachmentCount = 1;
subpass_description.pColorAttachments = &attachment_ref; subpass_description.pColorAttachments = &attachment_ref;
subpass_description.pDepthStencilAttachment = &depth_attachment_ref;
vk::SubpassDependency subpass_dependency = {}; vk::SubpassDependency subpass_dependency = {};
subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL; subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
subpass_dependency.dstSubpass = 0; subpass_dependency.dstSubpass = 0;
subpass_dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput; subpass_dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests;
subpass_dependency.dstStageMask = vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput); subpass_dependency.dstStageMask = vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests);
subpass_dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite; subpass_dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
std::vector<vk::AttachmentDescription> attachments = {color_attachment, depth_attachment_desc};
vk::RenderPassCreateInfo render_pass_info = {}; vk::RenderPassCreateInfo render_pass_info = {};
render_pass_info.attachmentCount = 1; render_pass_info.attachmentCount = attachments.size();
render_pass_info.pAttachments = &color_attachment; render_pass_info.pAttachments = attachments.data();
render_pass_info.subpassCount = 1; render_pass_info.subpassCount = 1;
render_pass_info.pSubpasses = &subpass_description; render_pass_info.pSubpasses = &subpass_description;
render_pass_info.dependencyCount = 1; render_pass_info.dependencyCount = 1;
@ -600,6 +557,13 @@ int main()
vk::RenderPass render_pass = device.createRenderPass(render_pass_info); vk::RenderPass render_pass = device.createRenderPass(render_pass_info);
vk::PipelineDepthStencilStateCreateInfo depht_stencil_info;
depht_stencil_info.depthTestEnable = VK_TRUE;
depht_stencil_info.depthWriteEnable = VK_TRUE;
depht_stencil_info.depthCompareOp = vk::CompareOp::eLessOrEqual;
depht_stencil_info.depthBoundsTestEnable = VK_FALSE;
depht_stencil_info.stencilTestEnable = VK_FALSE;
vk::GraphicsPipelineCreateInfo pipeline_info = {}; vk::GraphicsPipelineCreateInfo pipeline_info = {};
pipeline_info.stageCount = 2; pipeline_info.stageCount = 2;
pipeline_info.pStages = pipeline_shaders.data(); pipeline_info.pStages = pipeline_shaders.data();
@ -609,6 +573,7 @@ int main()
pipeline_info.pRasterizationState = &raster_info; pipeline_info.pRasterizationState = &raster_info;
pipeline_info.pMultisampleState = &multisampling_info; pipeline_info.pMultisampleState = &multisampling_info;
pipeline_info.pColorBlendState = &color_blend_info; pipeline_info.pColorBlendState = &color_blend_info;
pipeline_info.pDepthStencilState = &depht_stencil_info;
pipeline_info.layout = pipeline_layout; pipeline_info.layout = pipeline_layout;
pipeline_info.renderPass = render_pass; pipeline_info.renderPass = render_pass;
pipeline_info.subpass = 0; pipeline_info.subpass = 0;
@ -630,25 +595,59 @@ int main()
for (auto &view: image_views) for (auto &view: image_views)
{ {
std::vector<vk::ImageView> view_attachments = {view, depth_image_view};
vk::FramebufferCreateInfo framebuffer_info = vk::FramebufferCreateInfo(vk::FramebufferCreateFlags(), vk::FramebufferCreateInfo framebuffer_info = vk::FramebufferCreateInfo(vk::FramebufferCreateFlags(),
render_pass, view, framebuffer_extension.width, render_pass, view, framebuffer_extension.width,
framebuffer_extension.height, 1); framebuffer_extension.height, 1);
framebuffer_info.attachmentCount = view_attachments.size();
framebuffer_info.pAttachments = view_attachments.data();
framebuffers.push_back(device.createFramebuffer(framebuffer_info)); framebuffers.push_back(device.createFramebuffer(framebuffer_info));
} }
quad play{};
play.box = player; std::vector<vertex_3d> vertices;
play.vertices = {
{{-0.05f, -0.1f}, {1.0f, 0.0f, 0.0f}}, std::vector<vertex_3d> front_quad
{{0.05f, -0.1f}, {1.0f, 0.0f, 0.0f}}, {
{{0.05f, 0.1f}, {0.0f, 1.0f, 0.0f}}, {{-0.2f, -0.2f, 0.0f}, {1.0f, 0.0f, 0.0f}},
{{-0.05f, 0.1f}, {0.0f, 0.0f, 1.0f}} {{ 0.0f, -0.2f, 0.0f}, {1.0f, 0.0f, 0.0f}},
{{ 0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
{{-0.2f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}}
}; };
play.vertices = convert_quad_to_triangles(play.vertices); add_quad_to_vertices(vertices, front_quad);
auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertex) * 6 * 100);
vk::DeviceMemory vertex_memory = ret.first; std::vector<vertex_3d> back_quad
{
{{-0.15f, -0.15f, 0.2f}, {1.0f, 0.0f, 1.0f}},
{{ 0.05f, -0.15f, 0.2f}, {1.0f, 0.0f, 1.0f}},
{{ 0.05f, 0.05f, 0.2f}, {1.0f, 0.0f, 1.0f}},
{{-0.15f, 0.05f, 0.2f}, {1.0f, 0.0f, 1.0f}}
};
add_quad_to_vertices(vertices, back_quad);
std::vector<vertex_3d> right_quad
{
{{0.0f, -0.2f, 0.0f}, {0.0f, 1.0f, 0.0f}},
{{ 0.05f, -0.15f, 0.2f}, {0.0f, 1.0f, 0.0f}},
{{ 0.05f, 0.05f, 0.2f}, {0.0f, 1.0f, 0.0f}},
{{0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}}
};
add_quad_to_vertices(vertices, right_quad);
std::vector<vertex_3d> bottom_quad
{
{front_quad[3].position, {1.0f, 1.0f, 0.0f}},
{front_quad[2].position, {1.0f, 1.0f, 0.0f}},
{back_quad[2].position, {1.0f, 1.0f, 0.0f}},
{back_quad[3].position, {1.0f, 1.0f, 0.0f}}
};
std::println("Bottom quad");
add_quad_to_vertices(vertices, bottom_quad);
auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertices[0]) * vertices.size());
vk::DeviceMemory vertex_buffer_memory = ret.first;
vk::Buffer vertex_buffer = ret.second; vk::Buffer vertex_buffer = ret.second;
char *vertex_data = (char *)device.mapMemory(vertex_memory, 0, sizeof(vertex) * 6 * 100); // 100 quads char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, sizeof(vertices[0]) * vertices.size());
memcpy(vertex_data, play.vertices.data(), sizeof(play.vertices[0]) * play.vertices.size()); memcpy(data, vertices.data(), sizeof(vertices[0]) * vertices.size());
vk::CommandPoolCreateInfo command_pool_info = {}; vk::CommandPoolCreateInfo command_pool_info = {};
@ -660,6 +659,7 @@ int main()
vk::CommandBufferLevel::ePrimary, vk::CommandBufferLevel::ePrimary,
1); 1);
auto command_buffers = device.allocateCommandBuffers(cmd_alloc_info); auto command_buffers = device.allocateCommandBuffers(cmd_alloc_info);
vk::DescriptorPoolSize descriptor_pool_size(vk::DescriptorType::eUniformBuffer, sizeof(uniform)); vk::DescriptorPoolSize descriptor_pool_size(vk::DescriptorType::eUniformBuffer, sizeof(uniform));
vk::DescriptorPoolCreateInfo descriptor_pool_info; vk::DescriptorPoolCreateInfo descriptor_pool_info;
descriptor_pool_info.maxSets = 1; descriptor_pool_info.maxSets = 1;
@ -699,34 +699,22 @@ int main()
player.x = 0.0f; player.x = 0.0f;
player.y = 0.0f; player.y = 0.0f;
player.height = 0.2f; player.height = 0.2f;
player.width = 0.1f; player.width = 0.2f;
//velocityX = 0.008f; //velocityX = 0.008f;
std::vector<vertex_3d> render_vertices = vertices;
float angle = 0.0f; float angle = 0.0f;
float vel2 = 0.005f; float vel2 = 0.005f;
//std::thread phy_thread(simple_physics); //std::thread phy_thread(simple_physics);
glfwSetKeyCallback(window, keyboard_handle);
auto before = clock::now(); auto before = clock::now();
player.accY = 1.3f;
player.x = -0.8;
player.y = -0.5;
play.box = player;
std::vector<quad> enemies;
bool on_ground = true;
int jumps = 0;
int score = 0;
while(!glfwWindowShouldClose(window)) while(!glfwWindowShouldClose(window))
{ {
glfwPollEvents(); glfwPollEvents();
std::vector<vertex> render_vertices = play.vertices;
auto res_wait = device.waitForFences(next_frame_fence, VK_TRUE, UINT64_MAX); auto res_wait = device.waitForFences(next_frame_fence, VK_TRUE, UINT64_MAX);
if (res_wait != vk::Result::eSuccess) if (res_wait != vk::Result::eSuccess)
throw std::runtime_error("failed waiting!"); throw std::runtime_error("failed waiting!");
device.resetFences(next_frame_fence); device.resetFences(next_frame_fence);
if (skip_rendering) if (skip_rendering)
{
continue; continue;
}
auto image_result = device.acquireNextImageKHR(swapchain, UINT64_MAX, image_semaphore); auto image_result = device.acquireNextImageKHR(swapchain, UINT64_MAX, image_semaphore);
if (image_result.result != vk::Result::eSuccess) if (image_result.result != vk::Result::eSuccess)
{ {
@ -734,77 +722,25 @@ int main()
} }
uint32_t image_index = image_result.value; uint32_t image_index = image_result.value;
vkResetCommandBuffer(command_buffers[0], 0); vkResetCommandBuffer(command_buffers[0], 0);
if (enemies.empty())
{
quad enemy{};
std::mt19937 rng2(dev());
enemy.box = spawn_enemy(rng2);
enemy.vertices = bounding_box_to_vertices(enemy.box);
enemy.trans.transform = glm::mat4{1.0f};
enemies.push_back(enemy);
}
auto time_elapsed = clock::now() - before; auto time_elapsed = clock::now() - before;
if (pressed_space == true) simple_physics_step(std::chrono::duration_cast<std::chrono::duration<float>>(time_elapsed).count());
{
#ifndef NDEBUG
//std::println("JUMP!");
#endif
if (on_ground || jumps <= 1)
{
if (jumps <= 1)
play.box.velocityY = -1.2f;
on_ground = false;
jumps++;
std::println("Jumps {}", jumps);
}
pressed_space = false;
}
if (pressed_shift == true)
{
play.box.velocityY = 3.0f;
pressed_shift = false;
}
bool end_game = false;
if (stop_physics == false)
end_game = simple_physics_step(std::chrono::duration_cast<std::chrono::duration<float>>(time_elapsed).count(), play.box, enemies, on_ground);
if (on_ground)
jumps = 0;
if (end_game == true)
{
std::println("You lost!");
std::println("Your score was {}", score);
stop_physics = true;
#ifndef NDEBUG
std::println("Collision between pos x: {} y: {} and pos x: {} and pos y: {} ", play.box.x, play.box.y, enemies[0].box.x, enemies[0].box.y);
std::println("With width: {} and height: {} and width: {} and height: {}", play.box.width, play.box.height, enemies[0].box.width, enemies[0].box.height);
std::println("Rightmost vertex in position {} collided with leftmost vertex in position {}", play.box.x + play.box.width/2, enemies[0].box.x - enemies[0].box.width/2);
std::println("Jumps {}", jumps);
#endif
}
before = clock::now(); before = clock::now();
play.trans.transform = move({play.box.x, play.box.y});
for (auto &e: enemies) //u.transform = glm::rotate(u.transform, 0.01f, glm::vec3(1.0f, 0.0f, 1.0f));
{ //u.transform = move({player.x, player.y}) * rotate(angle);
if (e.box.x + e.box.width/2 <= -1.0f)
{
score += (int)(abs((e.box.width * 10)) + abs((e.box.height * 10)) + abs((e.box.velocityX * 10)));
enemies.clear();
break;
}
e.trans.transform = move({e.box.x, e.box.y});
add_quad_to_vertices(render_vertices, e.vertices);
}
//memcpy(uniform_data, &u, sizeof(uniform)); //memcpy(uniform_data, &u, sizeof(uniform));
angle -= 0.01f; angle -= 1.0f;
memcpy(vertex_data, render_vertices.data(), sizeof(render_vertices[0]) * render_vertices.size()); memcpy(data, render_vertices.data(), sizeof(vertices[0]) * vertices.size());
vk::CommandBufferBeginInfo begin_info = {}; vk::CommandBufferBeginInfo begin_info = {};
vk::ClearValue clear_color = vk::ClearValue({0.0f, 0.0f, 0.0f, 1.0f}); std::array<vk::ClearValue, 2> clear_values;
clear_values[0].color = vk::ClearColorValue(0.0f, 0.0f, 0.0f, 1.0f);
clear_values[1].depthStencil = {{1.0f, 0}};
vk::Rect2D render_area = {{0, 0}, framebuffer_extension}; vk::Rect2D render_area = {{0, 0}, framebuffer_extension};
vk::RenderPassBeginInfo render_pass_begin = vk::RenderPassBeginInfo(render_pass, framebuffers[image_index], vk::RenderPassBeginInfo render_pass_begin = vk::RenderPassBeginInfo(render_pass, framebuffers[image_index],
render_area, 1, &clear_color); render_area, clear_values.size(), clear_values.data());
vk::DeviceSize offset = 0; vk::DeviceSize offset = 0;
command_buffers[0].begin(begin_info); command_buffers[0].begin(begin_info);
command_buffers[0].beginRenderPass(render_pass_begin, vk::SubpassContents::eInline); command_buffers[0].beginRenderPass(render_pass_begin, vk::SubpassContents::eInline);
@ -813,23 +749,14 @@ int main()
//command_buffers[0].setScissor(0, scissor); //command_buffers[0].setScissor(0, scissor);
command_buffers[0].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, descriptor_sets, nullptr); command_buffers[0].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, descriptor_sets, nullptr);
command_buffers[0].bindVertexBuffers(0, 1, &vertex_buffer, &offset); command_buffers[0].bindVertexBuffers(0, 1, &vertex_buffer, &offset);
command_buffers[0].pushConstants(pipeline_layout, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push), &play.trans); command_buffers[0].draw(vertices.size(), 1, 0, 0);
command_buffers[0].draw(6, 1, 0, 0);
uint32_t offset_vertex = 6;
for (auto &e: enemies)
{
command_buffers[0].pushConstants(pipeline_layout, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push), &e.trans);
command_buffers[0].draw(6, 1, offset_vertex, 0);
offset_vertex += 6;
}
command_buffers[0].endRenderPass(); command_buffers[0].endRenderPass();
if (vkEndCommandBuffer(command_buffers[0]) != VK_SUCCESS) if (vkEndCommandBuffer(command_buffers[0]) != VK_SUCCESS)
{ {
throw std::runtime_error("Command buffer creation failed!"); throw std::runtime_error("Command buffer creation failed!");
} }
vk::PipelineStageFlags flags(vk::PipelineStageFlagBits::eColorAttachmentOutput); vk::PipelineStageFlags flags = vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput);
vk::SubmitInfo submit_info = vk::SubmitInfo(); vk::SubmitInfo submit_info = vk::SubmitInfo();
submit_info.waitSemaphoreCount = 1; submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = &image_semaphore; submit_info.pWaitSemaphores = &image_semaphore;
@ -854,15 +781,17 @@ int main()
} }
thread = false; thread = false;
//phy_thread.join(); //phy_thread.join();
device.unmapMemory(uniform_buffer_data); device.unmapMemory(vertex_buffer_memory);
device.unmapMemory(vertex_memory);
device.waitIdle(); device.waitIdle();
device.freeMemory(uniform_buffer_data);
device.freeMemory(depht_image_memory);
device.destroyBuffer(uniform_buffer);
device.destroyImageView(depth_image_view);
device.destroyImage(depth_image);
device.destroyDescriptorPool(descriptor_pool); device.destroyDescriptorPool(descriptor_pool);
device.destroyDescriptorSetLayout(descriptor_layout); device.destroyDescriptorSetLayout(descriptor_layout);
device.destroyBuffer(vertex_buffer); device.destroyBuffer(vertex_buffer);
device.destroyBuffer(uniform_buffer); device.freeMemory(vertex_buffer_memory);
device.freeMemory(vertex_memory);
device.freeMemory(uniform_buffer_data);
for (auto &framebuffer: framebuffers) for (auto &framebuffer: framebuffers)
{ {
device.destroyFramebuffer(framebuffer); device.destroyFramebuffer(framebuffer);

BIN
shaders/fragment.spv Normal file

Binary file not shown.

BIN
shaders/vertex.spv Normal file

Binary file not shown.

View file

@ -3,21 +3,17 @@
// x -> -1 (left) 1(right) // x -> -1 (left) 1(right)
// y -> -1 (top) 1(bottom) // y -> -1 (top) 1(bottom)
layout( push_constant ) uniform push{
mat4 transform;
}trans;
layout(binding = 0) uniform un{ layout(binding = 0) uniform un{
mat4 view; mat4 transform;
} view; } trans;
layout(location = 0) in vec2 in_position; layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_color; layout(location = 1) in vec3 in_color;
layout(location = 0) out vec3 frag_color; layout(location = 0) out vec3 frag_color;
void main() void main()
{ {
gl_Position = trans.transform * vec4(in_position, 0.0, 1.0); gl_Position = trans.transform * vec4(in_position, 1.0);
frag_color = in_color; frag_color = in_color;
} }