normalizing is a simple calculation, I would expect the function to
have one parameter - the vector to be normalised. Why does it have
two? could somebody write an example of how I would use it?
Normalizing is, indeed, relatively simple. It's also an operation that is performed often and consequently should be very fast. Performance considerations are especially important when designing math library middleware like D3DX.
The reason there are two parameters is for efficiency, and to some extent robustness. By providing by-reference (via pointer) output and input parameters, the D3DX normalize function can normalize a vector in place or to a new vector without unnecessary by-value copying of the vector object.
By way of contrast, consider the alternatives: If the normalization function took only a single input vector, it would have only two reasonable options to get the result back to the caller:
- Return it directly.
- Modify the input value.
Option (1) would perforce require a copy of the vector to be returned on the stack (a vector which is much larger than the size of a pointer in real-world scenarios) and so would be somewhat less efficient, even if it is a slightly more natural or convenient API.
Option (2) is cumbersome, would prevent const variables from being normalized without first making a copy, and similarly would require the caller to create a copy if they did not what the input vector modified. So it's both less convenient and in some cases also less efficient.
Update: It's worth noting, as discussed in the comments, that modern C++ compilers can perform a copy elision optimization that would allow them to eliminate the performance overhead of (1) entirely. This optimization was prevalent even back in 2011 when I originally answered this, so I should have pointed it out then.
I can only speculate as to why the designers of the API in question chose to implement it in this fashion; perhaps they were being conservative or had reason to expect that RVO wouldn't or couldn't be performed in some important use cases (by contrast, you can see some API's like Apple's GLKit aggressive expect these sorts of optimizations, even in C, because they return entire objects like matrices on the stack; this may also be informed by knowledge of the underlying platforms calling convention, as well, however).