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.
What is âswizzlingâ
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:
1 | 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++.
Basic swizzling in template
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.
1 | 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.
Swizzling for multi-dimension vector classes
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:
1 |
|
Now letâs use template parameter pack to implement swizzle for multi-dimensional vectors. The code looks like:
1 | template<template<typename> class TT, typename T, int ... Indexes> |
At the end
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.