Rendering¶
Initialization¶
The rendering API is very basic and supports only the most basic functionality.
Create an instance of Vortex2D::Renderer::Instance
which is then used to create an instance of Vortex2D::Renderer::Device
.
The device is then used to create any other object. The main one is the Vortex2D::Renderer::RenderWindow
which is a window where to render sprites and polygons.
The function Vortex2D::Fluid::RenderWindow::Display()
is then used to present the result to the screen.
Vortex2D::Renderer::Instance instance("Application name", extensions); // pass list of required extensions
Vortex2D::Renderer::Device device(instance.GetPhysicalDevice(), surface);
Vortex2D::Renderer::RenderWindow window(device, surface, width, height);
Note that the instance requires a list of extensions necessary to create a window. With GLFW they can be retrived as:
std::vector<const char*> GetGLFWExtensions()
{
std::vector<const char*> extensions;
unsigned int glfwExtensionCount = 0;
const char** glfwExtensions;
// get the required extensions from GLFW
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
for (unsigned int i = 0; i < glfwExtensionCount; i++)
{
extensions.push_back(glfwExtensions[i]);
}
return extensions;
}
In addition, you also need to create a surface which can be also done with the help of GLFW:
vk::UniqueSurfaceKHR GetGLFWSurface(GLFWwindow* window, vk::Instance instance)
{
// create surface
VkSurfaceKHR surface;
if (glfwCreateWindowSurface(static_cast<VkInstance>(instance), window, nullptr, &surface) != VK_SUCCESS)
{
throw std::runtime_error("failed to create window surface!");
}
return vk::UniqueSurfaceKHR(surface, vk::SurfaceKHRDeleter{instance});
}
Rendering shapes¶
We are now ready to draw things on the screen. Let’s start with some shapes like rectangles and circles:
Vortex2D::Renderer::Rectangle rectangle(device, {100.0f, 100.0f});
Vortex2D::Renderer::Ellipse circle(device, {50.0f, 50.0f});
rectangle.Colour = {1.0f, 0.0f, 0.0f, 1.0f};
rectangle.Position = {200.0f, 100.0f};
circle.Colour = {0.0f, 0.0f, 1.0f, 1.0f};
circle.Position = {500.0f, 400.0f};
auto blendMode = vk::PipelineColorBlendAttachmentState()
.setBlendEnable(true)
.setAlphaBlendOp(vk::BlendOp::eAdd)
.setColorBlendOp(vk::BlendOp::eAdd)
.setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
.setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
.setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
.setDstAlphaBlendFactor(vk::BlendFactor::eZero);
// note that rectangle, circle and render need to be alive for the duration of the rendering
auto render = renderTarget.Record({rectangle, circle}, blendMode);
render.Submit();
Rendering textures¶
Of course we can also render textures, using sprites.
Vortex2D::Renderer::Texture texture(device, 100, 100, vk::Format::eR8G8B8A8Unorm);
Vortex2D::Renderer::Sprite sprite(device, texture);