#include import Crafter.Event; import Crafter.Graphics; using namespace Crafter; /* This typedefs a shader configuration we will use, this includes all necessary info to load in the shader from a file. */ typedef VulkanShader< "MeshShaderXYZ.spirv", //the filename of the shader "main", //the name of the entrypoint symbol of the shader VK_SHADER_STAGE_MESH_BIT_EXT, //the shader stage 3, //how many descriptors this shader has {{{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2}}}//an array of descriptor types and their binding slot, 1 unfiform for the mvp and 2 for vertex and index. > MeshShaderSpirv; typedef VulkanShader<"FragmentShaderSolidWhite.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT, 0, {}> FragmentShader; /* This typedefs the pipeline we will use, for each combination of mesh and fragment shader a new pipeline must be used, but this pipeline can be shared with each object using this combination. */ typedef VulkanPipeline Pipeline; int main() { VulkanDevice::CreateDevice(); WindowWaylandVulkan window("HelloWindow", 1280, 720); /* Each shader and pipeline must be created before use. */ MeshShaderSpirv::CreateShader(); FragmentShader::CreateShader(); Pipeline::CreatePipeline(); /* Create a mesh typed on Vertex, which is a vertex type with only a position, it holds 3 vertexes and 3 indexes for our triangle. */ Mesh triangle(3, 3); triangle.verticies.value[0] = {0, -0.3, 0, 1}; triangle.verticies.value[1] = {0.3, 0.3, 0, 1}; triangle.verticies.value[2] = {-0.3, 0.3, 0, 1}; triangle.indicies.value[0] = 0; triangle.indicies.value[1] = 1; triangle.indicies.value[2] = 2; /* Use the created traingle mesh in a meshShader to render it. */ MeshShader meshShader(&triangle); /* Create a DescriptorSet to hold the descriptors of our meshShader, since our fragment shader doesn't use any. We are writing to the 0 index in the set because the mesh shader is the first stage. For fragment shaders write to the 1 index. */ DescriptorSet descriptors; meshShader.WriteDescriptors(descriptors.set[0]); /* Create a listener on the window onDraw event that gets a command buffer, this event is called for each frame and where drawing happens. */ EventListener listener(&window.onDraw, [&descriptors, &meshShader](VkCommandBuffer cmd){ /* Bind the descriptor set we created earlier, CreatePipeline() creates Pipeline::pipelineLayout and Pipeline::pipeline. */ vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL); /* Bind our pipeline, these can use static members because of the templating. */ vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline); /* Launch our mesh shader with the required threads. */ VulkanDevice::vkCmdDrawMeshTasksEXTProc(cmd, meshShader.threadCount, 1, 1); }); window.StartSync(); }