Example #1
0
bool GLView::getViewport(Camera::Viewport& v) const
{
	v.x=(int)x; v.y=(int)y; v.w=(int)w; v.h=(int)h;
	v.setCameraMatrix(modelview);
	const Matrix4& p=projection;

	//now the projmat...
	bool error=false;
	if(p(3,3)==One) {
		//ortho
		v.perspective=false;
		//m00=2/(r-l)=2/(w/scale)=scale*2/w;
		//m11=2/(t-b)=2/(h/scale)=scale*2/h;
		//m22=-2/(f-n)
		//m23=-(f+n)/(f-n)
		//[f*m22-n*m22=-2  ] => [m22   -m22 ] * [f] = [-2]
		//[f*m23-n*m23=-f-n]    [m23+1 -m23+1] * [n]   [0 ]
		v.scale=p(0,0)*(w/2);
		Matrix2 A;
		A(0,0)=p(2,2); A(0,1)=-p(2,2);
		A(1,0)=p(2,3)+1; A(1,1)=-p(2,3)+1;
		if(!A.inplaceInverse()) error=true;
		Vector2 nf;
		A.mul(Vector2(-2,Zero),nf);
		v.n=nf.x;
		v.f=nf.y;
		
#ifdef _DEBUG
		if(v.scale != p(1,1)*h*0.5) error=true;
		  //no projection translation
		if(p(0,3)!=Zero) error=true;
		if(p(1,3)!=Zero) error=true;
		//these ought to be zero
		if(p(3,2)!=Zero) error=true;
		if(p(3,1)!=Zero) error=true;
		if(p(3,0)!=Zero) error=true;
		if(p(2,1)!=Zero) error=true;
		if(p(2,0)!=Zero) error=true;
		if(p(1,0)!=Zero) error=true;
		if(p(1,2)!=Zero) error=true;
		if(p(0,2)!=Zero) error=true;
		if(p(0,1)!=Zero) error=true;
#endif
	}
	else if(p(3,3)==Zero) {
		//perspective
		v.perspective=true;
		//m00=2n/(r-l)=2n/n/scale=2*scale
		//m11=2n/(t-b)=2n/n/(aspect*scale)=2*aspect*scale
		//m22=-(f+n)/(f-n)
		//m23=-2fn/(f-n)
		//f*(m22+1)+n*(-m22+1)=0
		//f*m23 +n*(-m23)=2fn
		//f=n*(m22-1)/(m22+1)=n*c
		//so n*(c*m23-m23)=2*c*n*n
		//c*m23-m23=2*c*n
		v.scale=p(0,0)*Half;
		if(p(2,2)-One != Zero) {
			//solve for n
			Real c=(p(2,2)-1)/(p(2,2)+1);
			v.n=p(2,3)*Half-p(2,3)*Half/c;
			v.f=v.n*c;
		}
		else error=true;

#ifdef _DEBUG
		if(v.scale!=p(1,1)*Half*h/w) error=true;
		//no translation
		if(p(0,2)!=Zero) error=true;
		if(p(1,2)!=Zero) error=true;

		if(p(0,1)!=Zero) error=true;
		if(p(0,3)!=Zero) error=true;
		if(p(1,0)!=Zero) error=true;
		if(p(1,3)!=Zero) error=true;
		if(p(2,0)!=Zero) error=true;
		if(p(2,1)!=Zero) error=true;
		if(p(3,0)!=Zero) error=true;
		if(p(3,1)!=Zero) error=true;
		if(p(3,2)!=-One) error=true;
#endif
	}
	else error=true;
	
	if(error) {
	  fprintf(stderr,"GLView: There was an error in the projection matrix\n");
	  return false;
	}
	return true;
}