1. Thanks, I will rename it to "target"Okay.

2. I guess so

3. Because i'm using C I can't overload operators.No problem. And the implementation of sub(...) works as expected.

4. It should be fine, here's the code:The implementation is okay. However, the invocation is still questionable. Remember that the cross-product is not commutative, because

**a**x

**b**= - (

**b**x

**a**)

Hence the wrong order will yield in the reverse direction vector. IMHO you need to compute forward vector cross up vector to yield in the side vector, but you compute up vector cross forward vector and yield in the negative side vector. Please check this.

5. A little further down in the function I call setEqual which initialises the left parameter to the right parameter; In this cals rowY gets set to the up vector.Nonetheless, what happens "a little further down" doesn't interest the code above. Normalizing a vector means to keep its direction and ensure a length of 1. Now rowY is [0,0,0] at the moment of normalization, and hence has no non-vanishing direction and cannot be enlarged to have a length of 1. So normalize(&rowY) must die with an error like "division by zero".

*That*is the point I made.

6. I'll need to change this because my rowX is currently the cross of up and rowZ.Not sure if I understand you answer here, so I explain in detail what I mean. The orientation matrix you want to compute has the requirement that each row/column has a length of 1 and each pair of them is orthogonal. Your forward vector and up vectors are not necessarily orthogonal when createView is invoked, but the cross product of those 2 vectors will be orthogonal to both. So after the first cross product only 2 of the 3 required orthogonalities are guaranteed. Hence you need to compute a second cross-product to guarantee that the up vector is orthogonal to the other vectors, too. In summary:

side := forward x up

new_up := side x forward

7. I think I might be treating rows as columns because opengl is column-major.First, "column-major" is a term that describes how the elements of the 2D matrix construct are arranged linearly in 1D memory. That is not the topic I meant, although you have to consider it in your routines, of course.

What I meant is whether you use column-vectors, so that you do a matrix vector product like so

**p**' :=

**M***

**p**

or else row-vectors, so that you compute the same matrix vector product like so

**q**' :=

**q***

**N**

because there is a mathematical correspondence named the "transpose"

**p**:=

**q**

^{t}

**M**:=

**N**

^{t}

between them. Looking at a pure orientation matrix gives

**R**

^{t}=

**R**

^{-1}

so that confusing row and column vectors gives the inverse rotation. Confusing them when dealing with the position sub-matrix is even worse.

When you're using column-vectors (what is usual in OpenGL) then side, up, forward, and location vectors have to be set as

*columns*of the matrix.

Now coming to column-major (what is also usual in OpenGL): Make sure that the linear index is computed as

index = column * 4 + row

and it should work.

8. Brain exploded! So it should just be called the view matrix then?Yes, it is the view matrix.