Working with Vulkan

So, work on Fluxions 4.0 has begun. I started out by digging into Kristian Høgsberg Kristensens’ vkCube source code. I think he did a good job laying out all the essential pieces. Vulkan like OpenGL is a C library at heart. Instead of many state calls, you need to fill in data structures with all the important information. Unfortunately, the anonymous initializer lists that C uses are not compatible with C++, so instead I used that as an opportunity to go into the vulkan_core.h header file and see what these structs do.

One key piece of information is that you need to set all the non-essential parameters of every struct to zero or you likely will cause a crash. One method is to call memset to set the entire struct to 0, which I did initially, but I think the better way is to simply initialize all the members directly. And I won’t feel that I’m adding unnecessary calls to It helps with the learning process and since the whole process of programming with Vulkan is a bit verbose anyways, not a big deal. Another option that I considered was to encapsulate every Vulkan struct as a C++ class. But there is a substantial work cost involved given the vast number of different structures in the Vulkan library.

To initialize the Vulkan library, I use SDL 2.0 to create the window, initialize OS-dependent extensions, and create a surface to render to. Ultimately, this initialization takes about 500 lines of code. I need to add the ability to create a depth-stencil buffer in addition to the color buffer, but I do not think this will take too much effort. The functionality for initialization is going to located in the VulkanContext class. The main idea is to have code that looks like:

bool MyApp::init() {
  if (!context.init())
    return false;
}

void MyApp::render() {
  context.beginFrame();
  // render objects
  context.presentFrame();
}

The next concept to finalize is the render config. The render config is a thing I started in my WebGL LibXOR game engine. The idea matches the idea of the graphics pipeline in Vulkan. Of course, I was inspired by early talks about the architectures of Mantle, Direct3D, and Vulkan in hopes that I would be ready for it when I was ready to begin work with Vulkan. This has turned out to be a good strategy. While not finished, I hope to make the following code idea to be viable:

void MyApp::render() {
  context.beginFrame()
  if (config.use()) {
    config.setLights(lights)
    config.setMaterial(material)
    config.useTransformation(transformation)
    config.useTextures(textures)
    config.draw(geometry)
    config.restore()
  }
  context.endFrame()
}

Before I go down that road, I need to identify the material, geometry, and scene graph methodologies I want to use. The first is to use the Alias/Wavefront OBJ/MTL format which is great for static geometry. The second is to investigate the Autodesk (Filmbox) FBX format which supports animation. The third is to investigate Alembic which is an animation format for preserving animation. Lastly, I have taken a look at glTF which has a nice subset of features including animation. It may be worth my time to simply develop tools to convert these into a simpler system useful for direct upload in GPU buffers. I have played around with extending the Alias/Wavefront text file format and had good results in the past. I may keep that work and see what FBX or glTF ideas might be useful.

This last point is important because when you want to focus on physically-based rendering, you do not want to get too bogged down into a complex animation system. I do want to be able to tell animated stories with my graphics engine. But I have to balance it with the needs of the other components to my graphics engine.

So, the next work I need to do is to encapsulate the following ideas in Vulkan. How do I upload a texture map, create separate uniform buffer objects, and separate interleaved vertex array objects? Currently, I am working on abstracting the VkMemory and VkBuffer objects to make this process easier. Ultimately, I am working towards a smallish demo on using the new Ray Tracing features. Until then, Adios!

Leave a comment

Your email address will not be published. Required fields are marked *