0
101 Jun 12, 2009 at 13:31

Hi, i am trying to make a projection matrix for a software renderer im doing and i think ive nearly got it sorted but its not quite coming out right the code for setting the matrix is:

Matrix4X4 SoftwareCanvas::ProjectionMatrix(float FOV_horiz, float FOV_vert, float nearplane, float farplane, Matrix4X4 &m)
{
float h,w,q;

w= (float)1/tan(FOV_horiz*0.5);
h= (float)1/tan(FOV_vert*0.5);
q= farplane/(farplane-nearplane);

m.m11=w;
m.m22=h;
m.m33=q;
m.m34=1;
m.m43=-q*nearplane;

return m;

};


i set the FOV both FOV to pi/4 the near to 1 and the farplane to 1000

Then for each point in the triangle i transform it with the matrix

Point2D SoftwareCanvas::MatVec(Point3D v, Matrix4X4 m)
{
Point3D transvec(0,0,0,1);
transvec.x= v.x*m.m11+v.y*m.m21+v.z*m.m31+v.w*m.m41;
transvec.y= v.x*m.m12+v.y*m.m22+v.z*m.m32+v.w*m.m42;
transvec.z= v.x*m.m13+v.y*m.m23+v.z*m.m33+v.w*m.m43;
transvec.w= v.x*m.m14+v.y*m.m24+v.z*m.m34+v.w*m.m44;

Point2D newpoint(transvec.w*transvec.x/transvec.z,transvec.w*transvec.y/transvec.z);
return newpoint;

};


The problem is the perspective dosn’t look right it changes with a differant z value but its not really in perspective and there is not much defferance betweem 60 z and 600 z.
Has anyone got any ideas where im going wrong?
Thanks

#### 4 Replies

0
167 Jun 12, 2009 at 16:44

Hey, FYI, you can use the …[/code[b][/b]] tags to post code. Anyway, try looking at [url=http://www.opengl.org/sdk/docs/man/xhtml/glFrustum.xml]this[/url] which shows how the projection matrix is set up in OpenGL (they use the column matrix convention, so it’ll be transposed with respect to yours, and there may be some sign differences as well). From a quick look I see that your m33 appears to be missing a term and your m43 is missing a factor of 2. Also, the projection routine looks odd to me - in the ‘newpoint’ line, why are you taking each component and multiplying by w, then dividing by z? You should just need to divide by w. Note that the projection matrix moves z into w (that’s what the m34 = 1 does). [code]…[/code**] tags to post code.

Anyway, try looking at this which shows how the projection matrix is set up in OpenGL (they use the column matrix convention, so it’ll be transposed with respect to yours, and there may be some sign differences as well).

From a quick look I see that your m33 appears to be missing a term and your m43 is missing a factor of 2.

Also, the projection routine looks odd to me - in the ‘newpoint’ line, why are you taking each component and multiplying by w, then dividing by z? You should just need to divide by w. Note that the projection matrix moves z into w (that’s what the m34 = 1 does).

0
101 Jun 13, 2009 at 09:40

Ah thanks for the reply i will have a go at it

0
101 Jun 13, 2009 at 09:48

Just looking at that site you linked to im not quite sure what values to put in for GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top
is there a way to work them out or do you just put in values that you want?

Thanks

0
167 Jun 13, 2009 at 17:56

Ah, actually you don’t really need to worry about that, as your w and h calculations are correct already.

The left, right, bottom, top params are the coordinates of the corners of the view window, on the near clip plane. So in view space, the camera is at (0, 0, 0), and the view window goes from (left, bottom, nearClip) to (top, right, nearClip).

So for the usual case that you have some desired hfov and vfov, and you want the view window centered in front of the camera, you can calculate these as

left = -nearClip * tan(0.5 * hfov)
right = +nearClip * tan(0.5 * hfov)
bottom = -nearClip * tan(0.5 * vfov)
top = +nearClip * tan(0.5 * vfov)

But if you then plug these into the projection matrix formula you’ll see that the m11 and m22 parts come out just the same as what you already have, and the A and B values are zero as well.