Vulkan on Android 4 — Model Rendering Part 6

Jin-Long Wu
3 min readNov 19, 2018

--

Photo by Ronald Yang on Unsplash

We’ve prepared all the prerequisites we need and are able to construct our new scene which has earth with some lighting on.

New Render Pass

We need a render pass with a depth attachment for rendering a 3d model.

The majority of render pass creation is pretty much the same as we did before, and it only differs that we attach an extra depth attachment. The stencilLoadOp and stencilStoreOp both being VK_ATTACHMENT_LOAD_OP_DONT_CARE indicates we do not have stencil buffer and because we don’t care about the content of depth attachment after a render pass instance is completed, storeOp is also VK_ATTACHMENT_LOAD_OP_DONT_CARE.

New Scene

EarthScene creates an EarthSceneRenderer which draws the rotating earth with Phong shading. In the update loop of the scene, it updates the model, view, and projection matrices of the earth with UpdateMVP.

New Scene Renderer

Constructor

EarthSceneRenderer contains Model(s)/ModelResource(s) to render, Texture2D(s) applied to the models, a VkSampler controlling how to sample textures, Buffer(s) storing the transform matrices about a model(s) and lighting related information. The depth image, memory, and image view are used for depth test. CommandBuffers records scene-dependent commands and submits them to a queue. And, _application is a typeless pointer to the application context.

Besides, descriptor and pipeline are concepts we have not mentioned, we‘ll check them out in the next article.

Instance and surface creation are the same as what EmptyScene did. For the scene, we request the feature samplerAnisotropy for a better quality of textures on surfaces that are at oblique viewing angles with respect to a perspective viewing camera when choosing a device. And as we said before, ColorDepthRenderPass is created for depth test.

Framebuffers, command pools, command buffers, fences and semaphores are allocated and created as EmptyScene did.

android_app pointer is used to reference the path of Activity related information, and in this case, it is used to access the model file at the path to the application. Once we get the model path we load the model data with Model::ReadFile with scaling. STBI_rgb_alpha indicates we want our pixels to be the RGBA format as possible as it can. However, I checked the stb_image.h and found it does not work for jpg files.

The number of the mipmap level of texture is calculated by taking the binary logarithm of the largest dimension of the texture since each level of mipmap images are a power of 2 smaller than the previous level, and note the adding 1 is that the original texture is a mipmap level as well.

Now having loaded the pixel and vertices, we can copy the pixels to an image and upload the vertices to a buffer with BuildTexture2D and UploadToGPU which we’ve explained in this and this.

Next, we build two uniform buffers and create mappings between the memories of the buffer. The first buffer is as the resource of the transform matrices of the model. The second one is as the resource of the lighting data. Because we’ll update the transform matrices every updating frame we are not going to unmap the mvpBuffer immediately.

If samplerAnisotropy is enabled, we set the value to 8 for a balance between performance and quality. Because we are drawing earth, a sphere-shaped object, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE is suitable for this shape due to avoiding a visible line between the junction of texture borders.

BuildDepthImage creates the depth image, allocates memory for it, creates the derived image view, and binds the memory to the image. VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT specifies that an image can be used to create a VkImageView suitable for use as a depth/stencil in a VkFramebuffer. VK_IMAGE_ASPECT_DEPTH_BIT specifies the depth aspect of an image is included in an image view, and if the image format includes stencil test, we should append VK_IMAGE_ASPECT_STENCIL_BIT, too.

Note we do not need to transition the image layout as we do in BuildTexture2D since we have specified the transition at the vkAttachmentDescription of ColorDepthRenderPass already.

--

--