Projection Matrices

Miscellaneous Forums/General Discussion/Projection Matrices

Does anyone have any good reading on the subject ( preferably without having to buy another book - the two I have on DX9 gloss over it with a load of old pony about the SDK functions which create one for you automatically. Great, but I bloody want to create my own! )

Something with a detailed explanation about what goes in each cell of the matrix, and a few examples would be a good start. I'm sure I can use projection matrices to force the aspect ratio of my game to be consistent between all monitor aspect ratios, but I can't find any documentation on it at all. All I end up with is explanations like "takes a projection matrix as the parameter )

The helper function(s) won't work for me. I need to understand all the issues here. Clipping, FOV, the whole kit.

No docs but here is some code :

Strict

Rem
bbdoc: Projection Matrix - How To Set Matrix For scales
End Rem
Module Indiepath.projmatrix

ModuleInfo "Version: 1.0"
ModuleInfo "Author: Tim Fisher"
ModuleInfo "License: Indiepath License for non warranted software"
ModuleInfo "Modserver:Indiepath"
'End Rem
?Win32
Import BRL.D3D7Max2D
?
Import BRL.GLMax2D

Type ProjectionMatrix
	Field Scale:Float
	Field width:Float
	Field height:Float
	Field depth:Float
	Field angle:Float
Rem
bbdoc:Initialise and create a new Projection Matrix Object
returns: Returns handle to object
about: Pass base resolution width, height and depth. Angle and scale are not currently implemented
End Rem	
	Function Initialise:ProjectionMatrix(width:Float=800,height:Float=600,depth:Float=2,angle:Float=0,scale:Float=1)
		Local p:ProjectionMatrix = New ProjectionMatrix
		p.width = width
		p.height = height
		p.scale = scale
		p.depth = depth
		p.angle = angle
		p.Set()
		Return p
	End Function
Rem
bbdoc: Free the matrix object
End Rem	
	Function Free(p:ProjectionMatrix)
		p = Null
	End Function
	

	Method Set()
?Win32
		If primarydevice.device = Null Then
			glMatrixMode GL_PROJECTION
			glLoadIdentity
			glOrtho 0,Self.width,Self.height,0,-1,1
			glMatrixMode GL_MODELVIEW
		Else
			Local matrix#[]
			
			Local sx:Float = (2.0/Self.Width) '* Cos(Self.Angle)
			Local sy:Float = (2.0/Self.Height) * Cos(Self.Angle)
			Local sx1:Float = -Sin(Self.Angle)
			Local sy1:Float = Sin(Self.Angle)
			
			matrix=[..
			sx		,0.0		,0.0			,0.0,..
			0.0		,-sy		,0.0			,0.0,..
			0.0		,0.0		,2.0/Self.depth	,0.0,..
			-1-(1.0/Self.width),1+(1.0/Self.height),1.0,1.0]
			primarydevice.Device.SetTransform(D3DTS_PROJECTION,matrix)
			
		EndIf
?MacOS
		glMatrixMode GL_PROJECTION
		glLoadIdentity
		glOrtho 0,Self.width,Self.height,0,-1,1
		glMatrixMode GL_MODELVIEW

?
	End Method
	
	Method Rotate(angle:Float)
		Self.Angle = angle
		Self.Set()
	End Method
Rem
bbdoc: Translate Mouse
returns: Translated x & y
about: Translates the mouse position depending on matrix settings.
End Rem		
	Method TranslateMouse(x# Var, y# Var)
		x# = (MouseX()/Float(GraphicsWidth()))*Self.Width
		y# = (MouseY()/Float(GraphicsHeight()))*Self.Height
	End Method
	


Thanks Tim, but is that just for 2d? I don't see any reference to things like near and far clipping planes, FOV, etc in there, and I would need those in 3d. Also, what is depth? Zbuffer precision or something?

Look at the OpenGL documentation, it explains it better even as a generic explanation.

It'll also explain it for a right-handed coordinate system, which will only serve to further confuse me when dealing with DX9, which is left-handed.