feat(renderer/vk): dynamic rendering
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is failing
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	continuous-integration/drone/push Build is failing
				
			This commit is contained in:
		
							parent
							
								
									97ca429d38
								
							
						
					
					
						commit
						736c37d2f1
					
				
					 11 changed files with 251 additions and 68 deletions
				
			
		|  | @ -75,10 +75,17 @@ void Device::initialize_logical_device() | |||
| 
 | ||||
| 	auto extensions = std::vector<const char *> { | ||||
| 		VK_KHR_SWAPCHAIN_EXTENSION_NAME, | ||||
| 		VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, | ||||
| 	}; | ||||
| 
 | ||||
| 	const auto dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures { | ||||
| 		.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, | ||||
| 		.dynamicRendering = true, | ||||
| 	}; | ||||
| 
 | ||||
| 	auto device_info = VkDeviceCreateInfo { | ||||
| 		.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, | ||||
| 		.pNext = &dynamic_rendering_features, | ||||
| 		.queueCreateInfoCount = static_cast<uint32_t>(queue_infos.size()), | ||||
| 		.pQueueCreateInfos = queue_infos.data(), | ||||
| 		.enabledExtensionCount = static_cast<uint32_t>(extensions.size()), | ||||
|  |  | |||
|  | @ -100,12 +100,16 @@ PFN_vkFreeMemory vk_free_memory {}; | |||
| 
 | ||||
| PFN_vkResetCommandBuffer vk_reset_command_buffer {}; | ||||
| 
 | ||||
| PFN_vkCmdBeginRendering vk_cmd_begin_rendering {}; | ||||
| PFN_vkCmdEndRendering vk_cmd_end_rendering {}; | ||||
| 
 | ||||
| PFN_vkGetPhysicalDeviceSurfaceSupportKHR vk_get_physical_device_surface_support {}; | ||||
| PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vk_get_physical_device_surface_capabilities {}; | ||||
| PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vk_get_physical_device_surface_formats {}; | ||||
| 
 | ||||
| auto vk_create_xlib_surface_khr = PFN_vkCreateXlibSurfaceKHR {}; | ||||
| auto vk_destroy_surface_khr = PFN_vkDestroySurfaceKHR {}; | ||||
| 
 | ||||
| // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
 | ||||
| 
 | ||||
| Instance::Instance() | ||||
|  | @ -392,6 +396,9 @@ void Instance::load_device_functions_impl(VkDevice device) | |||
| 	load_fn(vk_free_memory, "vkFreeMemory"); | ||||
| 	load_fn(vk_get_buffer_memory_requirements, "vkGetBufferMemoryRequirements"); | ||||
| 	load_fn(vk_reset_command_buffer, "vkResetCommandBuffer"); | ||||
| 
 | ||||
| 	load_fn(vk_cmd_begin_rendering, "vkCmdBeginRendering"); | ||||
| 	load_fn(vk_cmd_end_rendering, "vkCmdEndRendering"); | ||||
| } | ||||
| 
 | ||||
| auto Instance::enumerate_gpus() const -> std::vector<VkPhysicalDevice> | ||||
|  |  | |||
|  | @ -49,6 +49,17 @@ public: | |||
| 		return m_images.size(); | ||||
| 	} | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_image_view(uint32_t idx) -> VkImageView | ||||
| 	{ | ||||
| 		return m_image_views[idx]; | ||||
| 	} | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_image(uint32_t idx) -> VkImage | ||||
| 	{ | ||||
| 		return m_images[idx]; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	[[nodiscard]] auto create_framebuffers_for_pass(VkRenderPass pass) const | ||||
| 	    -> std::vector<VkFramebuffer>; | ||||
| 
 | ||||
|  |  | |||
|  | @ -113,16 +113,16 @@ Pass::Pass( | |||
| 		.blendConstants = { 0.0f, 0.0, 0.0, 0.0 }, | ||||
| 	}; | ||||
| 
 | ||||
| 	auto attachment_description = VkAttachmentDescription { | ||||
| 		.format = static_cast<Swapchain *>(swapchain)->get_format(), | ||||
| 		.samples = VK_SAMPLE_COUNT_1_BIT, | ||||
| 		.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, | ||||
| 		.storeOp = VK_ATTACHMENT_STORE_OP_STORE, | ||||
| 		.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, | ||||
| 		.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, | ||||
| 		.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, | ||||
| 		.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, | ||||
| 	}; | ||||
| 	// auto attachment_description = VkAttachmentDescription {
 | ||||
| 	// 	.format =,
 | ||||
| 	// 	.samples = VK_SAMPLE_COUNT_1_BIT,
 | ||||
| 	// 	.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
 | ||||
| 	// 	.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
 | ||||
| 	// 	.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
 | ||||
| 	// 	.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
 | ||||
| 	// 	.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | ||||
| 	// 	.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
 | ||||
| 	// };
 | ||||
| 
 | ||||
| 	auto color_attachment_ref = VkAttachmentReference { | ||||
| 		.attachment = 0, | ||||
|  | @ -144,21 +144,18 @@ Pass::Pass( | |||
| 		.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, | ||||
| 	}; | ||||
| 
 | ||||
| 	m_pass = m_device->create_pass( | ||||
| 	    VkRenderPassCreateInfo { | ||||
| 	        .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, | ||||
| 	        .attachmentCount = 1u, | ||||
| 	        .pAttachments = &attachment_description, | ||||
| 	        .subpassCount = 1u, | ||||
| 	        .pSubpasses = &subpass_description, | ||||
| 	        .dependencyCount = 1u, | ||||
| 	        .pDependencies = &pass_dependency, | ||||
| 	    } | ||||
| 	); | ||||
| 	auto color_format = static_cast<Swapchain *>(swapchain)->get_format(); | ||||
| 	auto rendering_info = VkPipelineRenderingCreateInfoKHR { | ||||
| 		.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, | ||||
| 		.colorAttachmentCount = 1u, | ||||
| 		.pColorAttachmentFormats = &color_format, | ||||
| 
 | ||||
| 	}; | ||||
| 
 | ||||
| 	m_pipeline = m_device->create_graphics_pipeline( | ||||
| 	    VkGraphicsPipelineCreateInfo { | ||||
| 	        .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | ||||
| 	        .pNext = &rendering_info, | ||||
| 	        .stageCount = static_cast<uint32_t>(shader_stages.size()), | ||||
| 	        .pStages = shader_stages.data(), | ||||
| 	        .pVertexInputState = &vertex_input, | ||||
|  | @ -170,14 +167,14 @@ Pass::Pass( | |||
| 	        .pColorBlendState = &color_blend, | ||||
| 	        .pDynamicState = &dynamic_state, | ||||
| 	        .layout = m_layout, | ||||
| 	        .renderPass = m_pass, | ||||
| 	        .renderPass = VK_NULL_HANDLE, | ||||
| 	        .subpass = 0u, | ||||
| 	        .basePipelineHandle = VK_NULL_HANDLE, | ||||
| 	        .basePipelineIndex = -1, | ||||
| 	    } | ||||
| 	); | ||||
| 
 | ||||
| 	m_framebuffers = static_cast<Swapchain *>(swapchain)->create_framebuffers_for_pass(m_pass); | ||||
| 	// m_framebuffers = static_cast<Swapchain *>(swapchain)->create_framebuffers_for_pass(m_pass);
 | ||||
| 
 | ||||
| 	m_device->destroy_shader_module(vertex_module); | ||||
| 	m_device->destroy_shader_module(fragment_module); | ||||
|  | @ -193,7 +190,7 @@ Pass::~Pass() | |||
| 	m_device->wait_idle(); | ||||
| 	m_device->destroy_framebuffers(m_framebuffers); | ||||
| 	m_device->destroy_pipeline(m_pipeline); | ||||
| 	m_device->destroy_pass(m_pass); | ||||
| 	// m_device->destroy_pass(m_pass);
 | ||||
| 	m_device->destroy_pipeline_layout(m_layout); | ||||
| } | ||||
| 
 | ||||
|  | @ -206,7 +203,8 @@ void Pass::replace_swapchain(const ISwapchain &swapchain) | |||
| 
 | ||||
| 	m_device->wait_idle(); | ||||
| 	m_device->destroy_framebuffers(m_framebuffers); | ||||
| 	m_framebuffers = static_cast<const Swapchain &>(swapchain).create_framebuffers_for_pass(m_pass); | ||||
| 	// m_framebuffers = static_cast<const Swapchain
 | ||||
| 	// &>(swapchain).create_framebuffers_for_pass(m_pass);
 | ||||
| } | ||||
| 
 | ||||
| auto Pass::create_module(lt::assets::Blob blob) -> VkShaderModule | ||||
|  |  | |||
|  | @ -29,11 +29,6 @@ public: | |||
| 
 | ||||
| 	void replace_swapchain(const ISwapchain &swapchain); | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_pass() -> VkRenderPass | ||||
| 	{ | ||||
| 		return m_pass; | ||||
| 	} | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_pipeline() -> VkPipeline | ||||
| 	{ | ||||
| 		return m_pipeline; | ||||
|  | @ -54,8 +49,6 @@ private: | |||
| 
 | ||||
| 	memory::NullOnMove<class Device *> m_device {}; | ||||
| 
 | ||||
| 	VkRenderPass m_pass = VK_NULL_HANDLE; | ||||
| 
 | ||||
| 	VkPipeline m_pipeline = VK_NULL_HANDLE; | ||||
| 
 | ||||
| 	VkPipelineLayout m_layout = VK_NULL_HANDLE; | ||||
|  |  | |||
|  | @ -143,12 +143,79 @@ void Renderer::replace_swapchain(ISwapchain *swapchain) | |||
| 
 | ||||
| void Renderer::record_cmd(VkCommandBuffer cmd, uint32_t image_idx) | ||||
| { | ||||
| 	auto cmd_begin_info = VkCommandBufferBeginInfo { | ||||
| 	const auto cmd_begin_info = VkCommandBufferBeginInfo { | ||||
| 		.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, | ||||
| 		.flags = {}, | ||||
| 		.pInheritanceInfo = nullptr, | ||||
| 	}; | ||||
| 
 | ||||
| 	const auto begin_frame_barrier = VkImageMemoryBarrier { | ||||
| 		.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, | ||||
| 		.srcAccessMask = {}, | ||||
| 		.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, | ||||
| 		.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, | ||||
| 		.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | ||||
|         .image = m_swapchain->get_image(image_idx), | ||||
|         .subresourceRange = VkImageSubresourceRange{ | ||||
|             .aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT, | ||||
|             .baseMipLevel   = 0u, | ||||
|             .levelCount     = VK_REMAINING_MIP_LEVELS, | ||||
|             .baseArrayLayer = 0u, | ||||
|             .layerCount     = VK_REMAINING_ARRAY_LAYERS, | ||||
|         }, | ||||
| 
 | ||||
| 	}; | ||||
| 
 | ||||
| 	const auto end_frame_barrier = VkImageMemoryBarrier { | ||||
| 		.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, | ||||
| 		.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, | ||||
| 		.dstAccessMask = {}, | ||||
| 		.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | ||||
| 		.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, | ||||
|         .image = m_swapchain->get_image(image_idx), | ||||
| 
 | ||||
|         .subresourceRange = VkImageSubresourceRange{ | ||||
|             .aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT, | ||||
|             .baseMipLevel   = 0u, | ||||
|             .levelCount     = VK_REMAINING_MIP_LEVELS, | ||||
|             .baseArrayLayer = 0u, | ||||
|             .layerCount     = VK_REMAINING_ARRAY_LAYERS, | ||||
|         }, | ||||
| 	}; | ||||
| 
 | ||||
| 	const auto scissor = VkRect2D { | ||||
| 		.offset = { .x = 0u, .y = 0u }, | ||||
| 		.extent = m_resolution, | ||||
| 	}; | ||||
| 
 | ||||
| 	const auto viewport = VkViewport { | ||||
| 		.x = 0.0f, | ||||
| 		.y = 0.0f, | ||||
| 		.width = static_cast<float>(m_resolution.width), | ||||
| 		.height = static_cast<float>(m_resolution.height), | ||||
| 		.minDepth = 0.0f, | ||||
| 		.maxDepth = 1.0f, | ||||
| 	}; | ||||
| 
 | ||||
| 	const auto color_attachment_info = VkRenderingAttachmentInfoKHR { | ||||
| 		.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, | ||||
| 		.imageView = m_swapchain->get_image_view(image_idx), | ||||
| 		.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | ||||
| 		.resolveMode = VK_RESOLVE_MODE_NONE, | ||||
| 		.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, | ||||
| 		.storeOp = VK_ATTACHMENT_STORE_OP_STORE, | ||||
| 		.clearValue = VkClearValue { .color = { 0.93, 0.93, 0.93, 1.0 } }, | ||||
| 	}; | ||||
| 
 | ||||
| 	const auto rendering_info = VkRenderingInfoKHR { | ||||
| 		.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR, | ||||
| 		.renderArea = scissor, | ||||
| 		.layerCount = 1, | ||||
| 		.colorAttachmentCount = 1, | ||||
| 		.pColorAttachments = &color_attachment_info, | ||||
| 
 | ||||
| 	}; | ||||
| 
 | ||||
| 	vkc(vk_begin_command_buffer(cmd, &cmd_begin_info)); | ||||
| 	vk_cmd_push_constants( | ||||
| 	    cmd, | ||||
|  | @ -158,46 +225,41 @@ void Renderer::record_cmd(VkCommandBuffer cmd, uint32_t image_idx) | |||
| 	    sizeof(FrameConstants), | ||||
| 	    &m_frame_constants | ||||
| 	); | ||||
| 
 | ||||
| 	auto clear_value = VkClearValue { | ||||
| 			.color = {  | ||||
|                 0.93, | ||||
|                 0.93, | ||||
|                 0.93, | ||||
|                1.0, | ||||
|             }, | ||||
| 		}; | ||||
| 
 | ||||
| 	auto pass_begin_info = VkRenderPassBeginInfo { | ||||
| 		.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, | ||||
| 		.renderPass = m_pass->get_pass(), | ||||
| 		.framebuffer = m_pass->get_framebuffers()[image_idx], | ||||
| 		.renderArea = { .offset = {}, .extent = m_resolution }, | ||||
| 		.clearValueCount = 1u, | ||||
| 		.pClearValues = &clear_value | ||||
| 	}; | ||||
| 	vk_cmd_begin_render_pass(cmd, &pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); | ||||
| 	vk_cmd_pipeline_barrier( | ||||
| 	    cmd, | ||||
| 	    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, | ||||
| 	    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, | ||||
| 	    0, | ||||
| 	    0, | ||||
| 	    nullptr, | ||||
| 	    0, | ||||
| 	    nullptr, | ||||
| 	    1, | ||||
| 	    &begin_frame_barrier | ||||
| 	); | ||||
| 	vk_cmd_begin_rendering(cmd, &rendering_info); | ||||
| 	vk_cmd_bind_pipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pass->get_pipeline()); | ||||
| 
 | ||||
| 	auto viewport = VkViewport { | ||||
| 		.x = 0.0f, | ||||
| 		.y = 0.0f, | ||||
| 		.width = static_cast<float>(m_resolution.width), | ||||
| 		.height = static_cast<float>(m_resolution.height), | ||||
| 		.minDepth = 0.0f, | ||||
| 		.maxDepth = 1.0f, | ||||
| 	}; | ||||
| 	vk_cmd_set_viewport(cmd, 0, 1, &viewport); | ||||
| 
 | ||||
| 	auto scissor = VkRect2D { | ||||
| 		.offset = { .x = 0u, .y = 0u }, | ||||
| 		.extent = m_resolution, | ||||
| 	}; | ||||
| 	vk_cmd_set_scissors(cmd, 0, 1, &scissor); | ||||
| 
 | ||||
| 	vk_cmd_draw(cmd, 3, 1, 0, 0); | ||||
| 	vk_cmd_end_render_pass(cmd); | ||||
| 	vk_cmd_end_rendering(cmd); | ||||
| 	vk_cmd_pipeline_barrier( | ||||
| 	    cmd, | ||||
| 	    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, | ||||
| 	    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, | ||||
| 	    0, | ||||
| 	    0, | ||||
| 	    nullptr, | ||||
| 	    0, | ||||
| 	    nullptr, | ||||
| 	    1, | ||||
| 	    &end_frame_barrier | ||||
| 	); | ||||
| 	vkc(vk_end_command_buffer(cmd)); | ||||
| } | ||||
| 
 | ||||
| void submit_sprite(const components::Sprite &sprite, const math::components::Transform &transform) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| } // namespace lt::renderer::vk
 | ||||
|  |  | |||
|  | @ -3,8 +3,10 @@ | |||
| #include <memory/reference.hpp> | ||||
| #include <ranges> | ||||
| #include <renderer/backend/vk/context/device.hpp> | ||||
| #include <renderer/backend/vk/data/buffer.hpp> | ||||
| #include <renderer/backend/vk/renderer/pass.hpp> | ||||
| #include <renderer/backend/vk/utils.hpp> | ||||
| #include <renderer/frontend/data/buffer.hpp> | ||||
| #include <renderer/frontend/renderer/pass.hpp> | ||||
| #include <renderer/frontend/renderer/renderer.hpp> | ||||
| 
 | ||||
|  | @ -34,6 +36,13 @@ public: | |||
| 		m_frame_constants = constants; | ||||
| 	} | ||||
| 
 | ||||
| 	void submit_sprite( | ||||
| 	    const components::Sprite &sprite, | ||||
| 	    const math::components::Transform &transform | ||||
| 	) override | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| private: | ||||
| 	void record_cmd(VkCommandBuffer cmd, uint32_t image_idx); | ||||
| 
 | ||||
|  |  | |||
|  | @ -88,6 +88,9 @@ extern PFN_vkUnmapMemory vk_unmap_memory; | |||
| extern PFN_vkFreeMemory vk_free_memory; | ||||
| 
 | ||||
| extern PFN_vkResetCommandBuffer vk_reset_command_buffer; | ||||
| 
 | ||||
| extern PFN_vkCmdBeginRendering vk_cmd_begin_rendering; | ||||
| extern PFN_vkCmdEndRendering vk_cmd_end_rendering; | ||||
| // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
 | ||||
| 
 | ||||
| } // namespace lt::renderer::vk
 | ||||
|  |  | |||
|  | @ -1,7 +1,9 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <math/components/transform.hpp> | ||||
| #include <memory/scope.hpp> | ||||
| #include <renderer/api.hpp> | ||||
| #include <renderer/components/sprite.hpp> | ||||
| #include <renderer/data/frame_constants.hpp> | ||||
| 
 | ||||
| namespace lt::renderer { | ||||
|  | @ -44,6 +46,11 @@ public: | |||
| 	virtual void replace_swapchain(class ISwapchain *swapchain) = 0; | ||||
| 
 | ||||
| 	virtual void set_frame_constants(FrameConstants constants) = 0; | ||||
| 
 | ||||
| 	virtual void submit_sprite( | ||||
| 	    const components::Sprite &sprite, | ||||
| 	    const math::components::Transform &transform | ||||
| 	) = 0; | ||||
| }; | ||||
| 
 | ||||
| } // namespace lt::renderer
 | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #include <camera/components.hpp> | ||||
| #include <math/algebra.hpp> | ||||
| #include <math/components/transform.hpp> | ||||
| #include <renderer/components/messenger.hpp> | ||||
| #include <renderer/components/sprite.hpp> | ||||
| #include <renderer/frontend/context/device.hpp> | ||||
| #include <renderer/frontend/context/gpu.hpp> | ||||
| #include <renderer/frontend/context/instance.hpp> | ||||
|  | @ -88,6 +90,13 @@ void System::tick(app::TickInfo tick) | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// for each sprite, submit a new "model matrix"  + "color" to go into the scene's SSBO
 | ||||
| 	for (auto &[id, sprite, transform] : | ||||
| 	     m_registry->view<components::Sprite, math::components::Transform>()) | ||||
| 	{ | ||||
| 		m_renderer->submit_sprite(sprite, transform); | ||||
| 	} | ||||
| 
 | ||||
| 	m_renderer->set_frame_constants({ .view_projection = perspective }); | ||||
| 	if (m_renderer->draw(m_frame_idx) != IRenderer::DrawResult::success) | ||||
| 	{ | ||||
|  |  | |||
							
								
								
									
										77
									
								
								modules/renderer/public/components/sprite.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								modules/renderer/public/components/sprite.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <assets/shader.hpp> | ||||
| #include <math/vec3.hpp> | ||||
| #include <memory/reference.hpp> | ||||
| 
 | ||||
| namespace lt::renderer::components { | ||||
| 
 | ||||
| enum class VertexFormat : uint8_t | ||||
| { | ||||
| 	r32_g32_b32_sfloat, | ||||
| 
 | ||||
| 	r32_g32_sfloat, | ||||
| }; | ||||
| 
 | ||||
| enum class VertexInputRate : uint8_t | ||||
| { | ||||
| 	per_vertex, | ||||
| 
 | ||||
| 	per_instance, | ||||
| }; | ||||
| 
 | ||||
| struct VertexInputAttributeDescriptipn | ||||
| { | ||||
| 	uint32_t location; | ||||
| 
 | ||||
| 	uint32_t binding; | ||||
| 
 | ||||
| 	uint32_t offset; | ||||
| 
 | ||||
| 	VertexFormat format; | ||||
| }; | ||||
| 
 | ||||
| struct VertexInputBindingDescription | ||||
| { | ||||
| 	uint32_t binding; | ||||
| 
 | ||||
| 	uint32_t stride; | ||||
| }; | ||||
| 
 | ||||
| /** Requires a math::components::Transform component on the same entity to be functional. */ | ||||
| struct Sprite | ||||
| { | ||||
| 	struct Vertex | ||||
| 	{ | ||||
| 		math::vec3 position; | ||||
| 
 | ||||
| 		math::vec3 color; | ||||
| 
 | ||||
| 		[[nodiscard]] constexpr static auto get_attributes() | ||||
| 		    -> std::array<VertexInputAttributeDescriptipn, 2> | ||||
| 		{ | ||||
| 			return { | ||||
| 				VertexInputAttributeDescriptipn { | ||||
| 				    .location = 0u, | ||||
| 				    .binding = 0u, | ||||
| 				    .offset = offsetof(Sprite::Vertex, position), | ||||
| 				    .format = VertexFormat::r32_g32_b32_sfloat, | ||||
| 
 | ||||
| 				}, | ||||
| 
 | ||||
| 				VertexInputAttributeDescriptipn { | ||||
| 				    .location = 1u, | ||||
| 				    .binding = 0u, | ||||
| 				    .offset = offsetof(Sprite::Vertex, color), | ||||
| 				    .format = VertexFormat::r32_g32_b32_sfloat, | ||||
| 				}, | ||||
| 			}; | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	memory::Ref<assets::ShaderAsset> vertex_shader; | ||||
| 
 | ||||
| 	memory::Ref<assets::ShaderAsset> fragment_shader; | ||||
| }; | ||||
| 
 | ||||
| } // namespace lt::renderer::components
 | ||||
		Loading…
	
	Add table
		
		Reference in a new issue