Vector Swizzling and Parameter Pack in C++
Recently I am interested in game engine and start reading articles with code in GameEngineFromScratch. Due to the “from scratch”, a self designed math library would never be ignored. In vector math computing, a handy feature called “swizzling” is widely used.
The two most popular rendering APIs, OpenGL and DirectX, both provide GPU computing acceleration. For using GPU for computation, we need to write our computation code in provided shader language: GLSL for OpenGL and HLSL for DirectX. These languages both support “swizzling” feature for vector computing. A simple sample of swizzling is shown below:
Vec2d vecA(1.0, 2.0); // should support multiple type like, int, float or double
Since this feature is handy in vector computing, let’s try implementing it in C++.
Because we are implementing vector for multiple base type (int, float, etc.), it first come with template. So let’s first implement swizzling of a 2d vector type with supporting on different base types.
template<template<typename> class TT, typename T, int A, int B>
Here we use “template of template” for the swizzle class, because our 2-dimensional vector type need to use the type for basic value.
The code above looks so far so good. However, consider about implementing 3d or 4d vector, there would be swizzle3d, swizzle4d, …, etc. which, make the code like a mess. In C++11, we could resolve this problem using template parameter pack.
The parameter pack makes us to declare one type of parameter without number constrains. It mostly used in function arguments and multiple arguments in template. Below is a small sample of variadic functions modified from here:
Now let’s use template parameter pack to implement swizzle for multi-dimensional vectors. The code looks like:
template<template<typename> class TT, typename T, int ... Indexes>
Template is really really powerful for creating efficient library.
The remaining part of our math library is filling various operator computations. These operation could be simply written in C++, or we can use single instruction, multiple data (SIMD) accelerate strategies like MMX, SSE, AVX (x86) or NEON (arm). I will following the step of GameEngineFromScratch and try to use ISPC (x86) from Intel.