We use Milkshape3D for modeling, so it makes sense to support loading .ms3d model files. I implemented basic loading code this morning, but it needs a lot of work. In its current state, it will only load a single triangle out of the model, and materials and animation are not taken into account. After I get some other parts of the rendering side of things finished, I plan on getting it to correctly load and display a cool looking 3D model that GreyKnight created.
The rest of the day was spent in getting the camera and the projection matrix working.
Something you should look out for when using a vertex shader to transform vertices: When the matrix is stored in the constant registers, by default each register represents a column of the matrix, not a row. This is called "column-major", and makes sense from an optimization point of view; if you are using row vectors, then the columns of the matrices will need to be accessed to perform transformations, and the rows will rarely be directly accessed (one exception would be in matrix multiplication). You can account for this by transposing your matrices before you place them in the registers.
To make the code more readable (and easier to write), I have created four specialized derivations of the generic matrix: RotateX, RotateY, RotateZ, and Translate. The names are pretty self-explanatory; RotateX represents a rotation about the x-axis, etc. and Translate represents a translation. This allows me to create a rotation or translation matrix by providing only a single argument (an angle or a vector, depending on the matrix).
On the subject of matrices, I have decided to use mOut = Transpose(mIn); rather than mOut = mIn.Transpose(); The latter implies that the matrix being transposed is being altered, which isn't the case (a copy of it is created and transposed). I don't much like mOut = Multiply(mL, mR); though, as this is a bit too messy in my opinion. For multiplication and similar operations, I have decided to use this format: mOut = mL*mR;