/* Crafter®.Graphics Copyright (C) 2025 Catcrafts® Catcrafts.net This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include //required for the camera matrix. import Crafter.Math; import Crafter.Event; import Crafter.Graphics; using namespace Crafter; typedef VulkanShader<"MeshShaderXYZ.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT, 3, {{{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2}}}> MeshShaderSpirv; typedef VulkanShader<"FragmentShaderSolidWhite.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT, 0, {}> FragmentShader; typedef VulkanPipeline Pipeline; int main() { VulkanDevice::CreateDevice(); MeshShaderSpirv::CreateShader(); FragmentShader::CreateShader(); Pipeline::CreatePipeline(); WindowWaylandVulkan window("HelloWindow", 1280, 720); /* Load the verticies and indicies for our cube. */ Mesh cube(8, 12); Vertex verticies[] { {-0.5f, -0.5f, -0.5f, 1.0f}, {-0.5f, -0.5f, 0.5f, 1.0f}, {-0.5f, 0.5f, -0.5f, 1.0f}, {-0.5f, 0.5f, 0.5f, 1.0f}, {0.5f, -0.5f, -0.5f, 1.0f}, {0.5f, -0.5f, 0.5f, 1.0f}, {0.5f, 0.5f, -0.5f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f} }; std::memcpy(cube.verticies.value, &verticies, sizeof(verticies)); uint32_t indicies[] { 0, 2, 1, 1, 2, 3, 4, 5, 6, 5, 7, 6, 0, 1, 5, 0, 5, 4, 2, 6, 7, 2, 7, 3, 0, 4, 6, 0, 6, 2, 1, 3, 7, 1, 7, 5 }; std::memcpy(cube.indicies.value, &indicies, sizeof(indicies)); /* Defines a perspective camera, with an FOV of 90, an aspect ratio of 16/9 a near clip of 0.01 and a far clip of 512. */ Camera camera(ToRadian(90), 1280.0f / 720.0f, 0.01, 512); camera.view = MatrixRowMajor::Translation(0, 0, -5); /* Calculates the viewprojection, must be called each time after updating the camera. */ camera.Update(); MeshShader meshShader(&cube, &camera); DescriptorSet descriptors; meshShader.WriteDescriptors(descriptors.set[0]); /* Calculates the modelviewprojection matrix. */ meshShader.Update(); float counter = 0; EventListener listener(&window.onDraw, [&descriptors, &meshShader, &counter](VkCommandBuffer cmd){ vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline); VulkanDevice::vkCmdDrawMeshTasksEXTProc(cmd, meshShader.threadCount, 1, 1); meshShader.transform = MatrixRowMajor::Rotation(counter, counter, 0); /* We edited the transform so must recalculate the model view projection matrix. */ meshShader.Update(); counter+=0.01; }); window.StartSync(); }