VKFS is a cross-platform and window system independ C++ framework that allows you to quickly create basic Vulkan objects for further work, such as Instance, Physical Device, Device, Command queues, Command buffers, synchronization objects and many other useful things.
The framework is fully working. If you notice a bug/missing functionality, write about it in issues tab. I will add new features as needed.
Note: These tutorials assume that you already have a working environment with a configured compiler and linked libraries.
The object that creates an Instance of your application.
Example:
auto instance = new VKFS::Instance("Application Name", "Engine name", [instanceExtensions: std::vector<const char*>], [enableValidationLayers: bool], [OPTIONAL API_VERSION=VK_API_VERSION_1_2: uint32_t]);
The object that picks up VkPhysicalDevice, creates VkDevice based on it, as well as command queues.
Example:
auto device = new VKFS::Device(instance, [deviceExtensions: std::vector<const char*>]);
An object that creates a swap chain and renderpass for it.
Example:
auto swapchain = new VKFS::Swapchain(device, [windowWidth: int], [windowHeight: int]);
The object that creates VkDescriptorSetLayout, VkDescriptorSet and everything necessary for this. Allows you to create a Descriptor for UBO, Sampler or Storage Buffer in just two lines.
Example:
auto descriptor = new VKFS::Descriptor(device, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, [shaderStage: VkShaderStageFlagBits]);
descriptor->createUBOSet(sizeof(YourUBOStructure));
OR
auto descriptor = new VKFS::Descriptor(device, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, [shaderStage: VkShaderStageFlagBits]);
descriptor->createSamplerSet([imageInfo: VkDescriptorImageInfo]);
An object that allows you to conveniently load and create a VkShaderModule
Example:
auto vertex = new VKFS::ShaderModule(device, "path/to/spv");
A simple abstraction over VkPipeline
and VkPipelineLayout
objects. Perfect for those who want
to get rid of the confusing boilerplate code and those who do not need a lot of settings.
Example:
auto pipeline = new VKFS::Pipeline(device, [vertexBindingDescription: VkVertexInputBindingDescription], [attributesDescription: std::vector<VkVertexInputAttributeDescription>],
[renderPass: VkRenderPass], [descriptors: std::vector<VKFS::Descriptor*>], [colorAttachmentCount = 1: int]);
pipeline->addShader(VKFS::VERTEX, vertex);
pipeline->addShader(VKFS::FRAGMENT, fragment);
...
pipeline->addShader([type: VKFS::ShaderType], [vertexShader: VKFS::ShaderModule*]); // You can add vertex, fragment and geometry shaders to pipeline
pipeline->build(); // Build the pipeline
After building you can get your ready to use objects:
pipeline->getPipelineLayout(); // Returns VkPipelineLayout
pipeline->getPipeline(); // Returns VkPipeline
You can also set some additional parameters(before pipeline->build();
):
pipeline->enablePushConstants(sizeof(YourPushConstantsStruct), [shaderType: VKFS::ShaderType]); // Enables push constants for your pipeline.
pipeline->enableDepthTest([state: bool]); // Enables or disables depth test. Enabled by default
pipeline->setCullMode([mode: VKFS::CullMode]); // Enables specified culling mode
pipeline->disableAttachment([attachment: VKFS::Attachment]); // Disables color or depth attachment. For example, you can disable color attachment if you need pipeline for shadow mapping
pipeline->enableAlphaChannel([state: bool]); // Enables or disables alpha blending
pipeline->setPolygonMode([mode: VKFS::PolygonMode]); // Changes polygon mode. VKFS::FILL by default
An object representing simple implementation of the offscreen renderer. Supports multiple color attachments(for example, if you need select bright fragment for bloom effect via two outputs of the fragment shader). You can also use it for shadow mapping(set color attachment count to 0 and enableDepthAttachment to true).
Example:
auto offscreenRenderer = VKFS::Offscreen(device, [synchronization: VKFS::Synchronization*], [colorAttachmentsCount: int], [enableDepthAttachment: bool], [width: int], [height: int], [imageFilter = OFFSCR_LINEAR: VKFS::OffscreenImageFilter]);
To begin renderpass just type:
offscreenRenderer->beginRenderpass([clearColorR = 0: int], [clearColorG = 0: int], [clearColorB = 0: int], [clearColorA = 0: int]);
... Your draw calls
offscreenRenderer->endRenderpass();
To get VkDescriptorImageInfo of specified attachment, use:
offscreenRenderer->getImageInfo([attachmentIndex = 0: int]);
If there no color attachments but depth attachment enabled, it returns descriptor image info to the depth attachment
This object allows you to create a buffer of vertices and indices using your vertex structure
Example:
auto vb = new VKFS::VertexBuffer<YourVertexStruct>(device, [vertices: std::vector<YourVertexStruct>], [indices: std::vector<uint32_t>]);
You can also use this with Push Constants:
auto vb = new VKFS::VertexBuffer<YourVertexStruct, YourPushConstantsStruct>(device, [vertices: std::vector<YourVertexStruct>], [indices: std::vector<uint32_t>]);
Next, before you draw, call
vb->pushPushConstants(yourPushConstants);
This object allows you to quickly upload image to Vulkan and use it in the future
Example:
auto image = new VKFS::Image(device, [imageWidth: int], [imageHeight: int], [pixelsRGBA32: void*], [generateMipMaps = true: bool], [imageFilter = VKFS::Linear: VKFS::ImageFilter]);
image->getDescriptorImageInfo(); // Returns VkDescriptorImageInfo of created image
image->getImage(); // Returns VkImage
image->getImageView(); // Returns VkImageView
image->getSampler(); // Returns VkSampler
image->getMipLevels(); // Returns mipmap levels as uint32_t
You can also create descriptor for image:
auto imageDescriptor = VKFS::Descriptor(device, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
imageDescriptor->createSamplerSet(image->getDescriptorImageInfo());
// To get VkDescriptorSet for current frame use
VkDescriptorSet setForShader = imageDescriptor->getSet(sync);
Example of uploading image using SDL_image.h
module:
SDL_Surface* image = IMG_Load("path/to/image.jpg");
image = SDL_ConvertSurfaceFormat(image, SDL_PIXELFORMAT_RGBA32, 0); // Strictly use RGBA32 format
void* pixels = image->pixels;
int width = image->w;
int height = image->h;
auto vulkanImage = new VKFS::Image(device, width, height, pixels);
auto imageDescriptor = VKFS::Descriptor(device, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
imageDescriptor->createSamplerSet(vulkanImage->getDescriptorImageInfo());
Extensions are an additional module to the main functionality of the framework. They can be removed from the project
without causing any errors. Include extensions: #include <VKFS_Extensions.h>
Allows you to quickly create vertices and indexes to them of shapes such as sphere, cube, pyramid, cylinder and cone. At the moment, this extension is still in development
Platform | Status |
---|---|
Windows(MSYS2 MinGW64) | ✔️ |
MacOS | ✔️ |
Linux(Debian 11) | ✔️ |
To build a framework, use CMake:
git clone https://github.com/MHDtA-dev/VKFS.git
cd VKFS
mkdir build
cd build
cmake ..
make
- "Context" class
- Offscreen Renderer class
- Images
- Screen post processing rect class
- Objects cleanup
- Shape Constructor
- Text renderer class
- Model importing via assimp