Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.h	(revision 2944)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.h	(revision 3062)
@@ -165,5 +165,6 @@
 Matrix4x4 GetFrustum(float left, float right, float bottom, float top, float near, float far);
 Matrix4x4 LookAt(const Vector3 &pos, const Vector3 &dir, const Vector3& up);
-
+Matrix4x4 GetOrtho(float fov, float aspect, float near, float far);
+Matrix4x4 GetPerspective(float fov, float aspect, float near, float far);
 
 }
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h	(revision 3061)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h	(revision 3062)
@@ -12,4 +12,5 @@
 class Matrix4x4;
 class Polyhedron;
+
 
 /** Class representing a frustum.
@@ -43,13 +44,8 @@
 class Camera
 {
-	friend class ShadowMap;
-
 public:
 	/** Default constructor.
 	*/
 	Camera();
-	/** Camera taking the image width and height and the field of view.
-	*/
-	Camera(float aspect, float fieldOfView = 90.f);
 	/** Sets the current camera position.
 	*/
@@ -71,10 +67,4 @@
 	Vector3 GetBaseUpVector() const;
 	Vector3 GetBaseRightVector() const;
-	/** Returns the field of view.
-	*/
-	inline float GetFov() const { return mFOVy; }
-	/** Returns the aspect ratio.
-	*/
-	inline float GetAspect() const { return mAspect; }
 	/** Sets up viewing matrices in for opengl rendering
 	*/
@@ -82,5 +72,5 @@
 	/** Returns the current projection matrix.
 	*/
-	void GetProjectionMatrix(Matrix4x4 &mat) const;
+	virtual void GetProjectionMatrix(Matrix4x4 &mat) const = 0;
 	/** Returns the current model view matrix.
 	*/
@@ -89,14 +79,4 @@
 	*/
 	void GetViewOrientationMatrix(Matrix4x4 &mat) const;
-	/** Calculates a frustum from the projection and the modelview matrix.
-	*/
-	void CalcFrustum(Frustum &frustum);
-	/** Computes the extremal points of this frustum.
-		If farthestVisibleDistance is nearer than the far plane, 
-		it is used to define the far plane instead.
-	*/
-	void ComputePoints(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
-		               Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
-					   float farthestVisibleDistance = 1e25f) const;
 	/** Returns the near plane.
 	*/
@@ -111,7 +91,4 @@
 	*/
 	void SetFar(float farDist);
-	/** Sets this camera to orthographic projection.
-	*/
-	//void SetOrtho(bool ortho);
 	/** Set yaw (rotation around vertical axis.
 	*/
@@ -132,7 +109,4 @@
 	*/
 	void SetDirection(const Vector3 &direction);
-	/** Returns frustum as polyhedron. 
-	*/
-	Polyhedron *ComputeFrustum(float farthestVisibleDistance = 1e25f) const;
 	/** Sets up projection matrix in OpenGl.
 	*/
@@ -141,5 +115,7 @@
 	*/
 	void SetupViewProjection();
-
+	/** Calculates a frustum from the projection and the modelview matrix.
+	*/
+	void CalcFrustum(Frustum &frustum);
 
 protected:
@@ -148,4 +124,57 @@
 
 	void CalculateFromPitchAndYaw();
+
+
+	////////////////
+	//-- members
+
+	float mNear;
+	float mFar;
+	
+	Matrix4x4 mBaseOrientation;
+	Matrix4x4 mViewOrientation;
+
+	float mPitch;
+	float mYaw;
+
+	Vector3 mPosition;
+};
+
+
+/** Classs representing a perspective camera.
+*/
+class PerspectiveCamera: public Camera
+{
+	friend class ShadowMap;
+
+public:
+	/** Default constructor.
+	*/
+	PerspectiveCamera();
+	/** Camera taking the image width and height and the field of view.
+	*/
+	PerspectiveCamera(float aspect, float fieldOfView = 90.f);
+	/** Returns the field of view.
+	*/
+	inline float GetFov() const { return mFOVy; }
+	/** Returns the aspect ratio.
+	*/
+	inline float GetAspect() const { return mAspect; }
+	/** Returns the current projection matrix.
+	*/
+	virtual void GetProjectionMatrix(Matrix4x4 &mat) const;
+	/** Computes the extremal points of this frustum.
+		If farthestVisibleDistance is nearer than the far plane, 
+		it is used to define the far plane instead.
+	*/
+	void ComputePoints(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
+		               Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
+					   float farthestVisibleDistance = 1e25f) const;
+	/** Returns frustum as polyhedron. 
+	*/
+	Polyhedron *ComputeFrustum(float farthestVisibleDistance = 1e25f) const;
+
+
+protected:
 
 	void ComputePointsInternal(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
@@ -159,21 +188,8 @@
 
 	float mFOVy;
-	float mNear;
-	float mFar;
-	
-	/// if this camera is orthgraphic or perspective
-	//bool mIsOrtho;
-
-	Matrix4x4 mBaseOrientation;
-	Matrix4x4 mViewOrientation;
-
-	float mPitch;
-	float mYaw;
-
-	Vector3 mPosition;
-
 	float mAspect;
 };
 
+
 }
 #endif
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Visualization.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Visualization.h	(revision 2889)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Visualization.h	(revision 3062)
@@ -9,4 +9,5 @@
 
 class Bvh;
+class PerspectiveCamera;
 class Camera;
 class RenderState;
@@ -23,5 +24,5 @@
 	    as parameters
 	*/
-	Visualization(Bvh *bvh, Camera *camera, Camera *vizCamera, RenderState *state);
+	Visualization(Bvh *bvh, PerspectiveCamera *camera, Camera *vizCamera, RenderState *state);
 
 	~Visualization();
@@ -38,5 +39,5 @@
 	/** Sets the currently used scene camera.
 	*/
-	void SetCamera(Camera *cam)  {mCamera = cam;}
+	void SetCamera(PerspectiveCamera *cam)  {mCamera = cam;}
 	/** Sets the current render state
 	*/
@@ -45,6 +46,5 @@
 	*/
 	void SetFrameId(int frameId);
-
-		/** Renders a camera frustum.
+	/** Renders a camera frustum.
 	*/
 	void RenderFrustum();
@@ -56,5 +56,5 @@
 
 	/// the current camera
-	Camera *mCamera;
+	PerspectiveCamera *mCamera;
 	/// the visualization camera
 	Camera *mVizCamera;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneQuery.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneQuery.cpp	(revision 3061)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneQuery.cpp	(revision 3062)
@@ -139,5 +139,5 @@
 	const float ylen = mSceneBox.Size().y * 0.5f;
 	
-	Camera *orthoCam = new Camera(xlen / ylen);
+	PerspectiveCamera *orthoCam = new PerspectiveCamera(xlen / ylen);
 	//orthoCam->SetOrtho(true);
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Visualization.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Visualization.cpp	(revision 2963)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Visualization.cpp	(revision 3062)
@@ -6,5 +6,4 @@
 #include "RenderState.h"
 #include "ShadowMapping.h"
-
 #include <stack>
 
@@ -70,5 +69,5 @@
 
 Visualization::Visualization(Bvh *bvh, 
-							 Camera *camera, 
+							 PerspectiveCamera *camera, 
 							 Camera *vizCamera, 
 							 RenderState *renderState): 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.h	(revision 3034)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.h	(revision 3062)
@@ -14,6 +14,7 @@
 class RenderTraverser;
 class Vector3;
-class Camera;
+class PerspectiveCamera;
 class DirectionalLight;
+
 
 /** This class implements a the computation of single shadow map using 
@@ -27,5 +28,5 @@
 		The shadow map has resolution size squared.
 	*/
-	ShadowMap(DirectionalLight *light, int size, const AxisAlignedBox3 &sceneBox, Camera *cam);
+	ShadowMap(DirectionalLight *light, int size, const AxisAlignedBox3 &sceneBox, PerspectiveCamera *cam);
 
 	~ShadowMap();
@@ -52,5 +53,5 @@
 	/** Returns the camera used for light view rendering.
 	*/
-	Camera *GetShadowCamera() const { return mShadowCam; }
+	PerspectiveCamera *GetShadowCamera() const { return mShadowCam; }
 	/** Renders the scene from shadow view using conventional shading.
 	*/
@@ -111,5 +112,5 @@
 	int mSize;
 	/// the shadow view
-	Camera *mShadowCam;
+	PerspectiveCamera *mShadowCam;
 	/// the texture matrix
 	Matrix4x4 mTextureMatrix;
@@ -117,5 +118,5 @@
 	DirectionalLight *mLight;
 	/// the scene camera
-	Camera *mCamera;
+	PerspectiveCamera *mCamera;
 
 	Matrix4x4 mLightProjView;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3038)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3062)
@@ -15,5 +15,5 @@
 class FrameBufferObject;
 class Vector3;
-class Camera;
+class PerspectiveCamera;
 class Matrix4x4;
 class ShadowMap;
@@ -36,5 +36,5 @@
 		exact scene size that was scaled in order to improve floating point precision.
 	*/
-	DeferredRenderer(int w, int h, Camera *cam, float scaleFactor);
+	DeferredRenderer(int w, int h, PerspectiveCamera *cam, float scaleFactor);
 	/** The algorithm renders the scene given an fbo consists of 1 color buffer, 
 		1 position buffer, and 1 normal buffer.
@@ -122,5 +122,5 @@
 	int mHeight;
 
-	Camera *mCamera;
+	PerspectiveCamera *mCamera;
 
 	bool mUseTemporalCoherence;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp	(revision 3061)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp	(revision 3062)
@@ -134,8 +134,8 @@
 
 
-ShadowMap::ShadowMap(DirectionalLight *light
-					 , int size, 
+ShadowMap::ShadowMap(DirectionalLight *light, 
+					 int size, 
 					 const AxisAlignedBox3 &sceneBox,
-					 Camera *cam):
+					 PerspectiveCamera *cam):
 mSceneBox(sceneBox), mSize(size), mCamera(cam), mLight(light)
 {
@@ -148,5 +148,5 @@
 
 
-	mShadowCam = new Camera(1);
+	mShadowCam = new PerspectiveCamera(1);
 	//mShadowCam->SetOrtho(true);
 }
@@ -713,3 +713,5 @@
 	glDisable(GL_POLYGON_OFFSET_FILL);
 }
+
+
 } // namespace
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3061)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3062)
@@ -79,7 +79,7 @@
 ShaderManager *shaderManager = NULL;
 /// the scene camera
-Camera *camera = NULL;
+PerspectiveCamera *camera = NULL;
 /// the scene camera
-Camera *visCamera = NULL;
+PerspectiveCamera *visCamera = NULL;
 /// the visualization
 Visualization *visualization = NULL;
@@ -257,5 +257,5 @@
 void CalcDecimalPoint(string &str, int d);
 /// Creates the traversal method (vfc, stopandwait, chc, chc++)
-RenderTraverser *CreateTraverser(Camera *cam);
+RenderTraverser *CreateTraverser(PerspectiveCamera *cam);
 
 /// place the viewer on the floor plane
@@ -369,5 +369,5 @@
 	///////////////////////////
 
-	camera = new Camera(winWidth / winHeight, fov);
+	camera = new PerspectiveCamera(winWidth / winHeight, fov);
 	camera->SetNear(nearDist);
 	camera->SetFar(1000);
@@ -376,5 +376,5 @@
 	camera->SetPosition(camPos);
 
-	visCamera = new Camera(winWidth / winHeight, fov);
+	visCamera = new PerspectiveCamera(winWidth / winHeight, fov);
 	visCamera->SetNear(0.0f);
 	visCamera->Yaw(.5 * M_PI);
@@ -661,5 +661,5 @@
 
 
-RenderTraverser *CreateTraverser(Camera *cam)
+RenderTraverser *CreateTraverser(PerspectiveCamera *cam)
 {
 	RenderTraverser *tr;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.cpp	(revision 2953)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.cpp	(revision 3062)
@@ -649,6 +649,6 @@
 }
 
-Matrix4x4 
-NormalTransformMatrix(const Matrix4x4 &tform)
+
+Matrix4x4  NormalTransformMatrix(const Matrix4x4 &tform)
 {
 	Matrix4x4 m = tform;
@@ -692,37 +692,8 @@
 	return m;
 }
-/*
-
-template<class REAL>
-Matrix4<REAL>& scaleTranslateToFit(Matrix4<REAL>& output, const Vector3<REAL>& vMin, const Vector3<REAL>& vMax) {
-	const REAL diffX = vMax.x()-vMin.x();
-	output[ 0] = 2/diffX;
-	output[ 4] = 0;
-	output[ 8] = 0;
-	output[12] = -(vMax.x()+vMin.x())/diffX;
-
-	const REAL diffY = vMax.y()-vMin.y();
-	output[ 1] = 0;
-	output[ 5] = 2/diffY;
-	output[ 9] = 0;
-	output[13] = -(vMax.y()+vMin.y())/diffY;
-
-	const REAL diffZ = vMax.z()-vMin.z();
-	output[ 2] = 0;
-	output[ 6] = 0;
-	output[10] = 2/diffZ;
-	output[14] = -(vMax.z()+vMin.z())/diffZ;
-
-	output[ 3] = 0;
-	output[ 7] = 0;
-	output[11] = 0;
-	output[15] = 1;
-	return output;
-}
+
+
+/** The resultig matrix that is equal to the result of glFrustum
 */
-
-
-
-//output is initialized with the same result as glFrustum
 Matrix4x4 GetFrustum(float left, float right, 
 					 float bottom, float top, 
@@ -781,3 +752,69 @@
 
 
-}
+/** The resultig matrix that is equal to the result of glOrtho
+*/
+Matrix4x4 GetOrtho(float left, float right, float bottom, float top, float far, float near)
+{
+	Matrix4x4 m;
+
+	const float xDif = 1.0f / (right - left);
+	const float yDif = 1.0f / (top - bottom);
+	const float zDif = 1.0f / (far - near);
+
+	m.x[0][0] = 2.0f * xDif;
+	m.x[0][1] = .0f;
+	m.x[0][2] = .0f;
+	m.x[0][3] = .0f;
+
+	m.x[1][0] = .0f;
+	m.x[1][1] = 2.0f * yDif;
+	m.x[1][2] = .0f;
+	m.x[1][3] = .0f;
+
+	m.x[2][0] = .0f;
+	m.x[2][1] = .0f;
+	m.x[2][2] = -2.0f * zDif;
+	m.x[2][3] = .0f;
+	
+	m.x[3][0] = (right + left) * xDif;
+	m.x[3][1] = (top + bottom) * yDif;
+	m.x[3][2] = (far + near) * zDif;
+	m.x[3][3] = 1.0f;
+
+	return m;
+}
+
+/** The resultig matrix that is equal to the result of gluPerspective
+*/
+Matrix4x4 GetPerspective(float fov, float aspect, float near, float far)
+{
+	Matrix4x4 m;
+
+	const float x = 1.0f / tan(fov * 0.5f);
+	const float zDif = 1.0f / (near - far);
+
+	m.x[0][0] = x / aspect;
+	m.x[0][1] = .0f;
+	m.x[0][2] = .0f;
+	m.x[0][3] = .0f;
+
+	m.x[1][0] = .0f;
+	m.x[1][1] = x;
+	m.x[1][2] = .0f;
+	m.x[1][3] = .0f;
+
+	m.x[2][0] = .0f;
+	m.x[2][1] = .0f;
+	m.x[2][2] = (far + near) * zDif;
+	m.x[2][3] = -1.0f;
+	
+	m.x[3][0] = .0f;
+	m.x[3][1] = .0f;
+	m.x[3][2] = 2.0f *(far * near) * zDif;
+	m.x[3][3] = 0.0f;
+
+	return m;
+}
+
+
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3057)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3062)
@@ -231,5 +231,5 @@
 
 
-DeferredRenderer::DeferredRenderer(int w, int h, Camera *cam, float scaleFactor):
+DeferredRenderer::DeferredRenderer(int w, int h, PerspectiveCamera *cam, float scaleFactor):
 mWidth(w), mHeight(h), 
 mCamera(cam),
@@ -298,5 +298,4 @@
 
 	i = 0;
-
 	sCgSsaoProgram->AddParameter("colors", i ++);
 	sCgSsaoProgram->AddParameter("normals", i ++);
@@ -314,5 +313,4 @@
 
 	i = 0;
-
 	sCgGiProgram->AddParameter("colors", i ++);
 	sCgGiProgram->AddParameter("normals", i ++);
@@ -529,4 +527,7 @@
 	sCgSsaoProgram->SetValue3f(10, tr.x, tr.y, tr.z);
 
+	cout << "new projview:\n" << projViewMatrix << endl;
+	cout << "old projview:\n" << oldProjViewMatrix << endl;
+
 	sCgSsaoProgram->SetMatrix(11, projViewMatrix);
 	sCgSsaoProgram->SetMatrix(12, oldProjViewMatrix);
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp	(revision 3061)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp	(revision 3062)
@@ -16,270 +16,8 @@
 
 
-Camera::Camera() 
-{
-	mFOVy = 60.0f * M_PI / 180.0f;
-	//mIsOrtho = false;
-	
-	SetPosition(Vector3(0, 0, 0));
-
-	mPitch = mYaw = 0;
-	Precompute(baseDir);
-
-	CalculateFromPitchAndYaw();
-}
-
-
-Camera::Camera(float aspect, float fieldOfView) 
-{
-	mFOVy = fieldOfView * M_PI / 180.0f;
-	mAspect = aspect;
-	//mIsOrtho = false;
-
-	SetPosition(Vector3::ZERO());
-
-	mPitch = mYaw = 0;
-	Precompute(baseDir);
-
-	CalculateFromPitchAndYaw();
-}
-
-
-void Camera::Precompute(const Vector3 &dir) 
-{
-	Vector3 up = Vector3::UNIT_Z();
-	
-	mBaseOrientation = LookAt(Vector3::ZERO(), dir, up);
-	mViewOrientation = mBaseOrientation;
-}
-
-
-void Camera::SetPosition(const Vector3 &pos) 
-{
-	mPosition = pos;
-}
-
-
-void Camera::SetNear(float nearDist) 
-{
-	mNear = nearDist;
-}
-
-
-void Camera::SetFar(float farDist) 
-{ 
-	mFar = farDist; 
-}
-
-
-void Camera::GetProjectionMatrix(Matrix4x4 &mat) const
-{
-	glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat.x);
-}
-
-
-void Camera::GetModelViewMatrix(Matrix4x4 &mat) const
-{
-	mat = mViewOrientation;
-
-	// note: left handed system => we go into positive z
-	mat.x[3][0] = -DotProd(GetRightVector(), mPosition);
-	mat.x[3][1] = -DotProd(GetUpVector(), mPosition);
-	mat.x[3][2] = DotProd(GetDirection(), mPosition);
-}
-
-
-void Camera::GetViewOrientationMatrix(Matrix4x4 &mat) const
-{
-	mat = mViewOrientation;
-}
-
-
-void Camera::CalcFrustum(Frustum &frustum)
-{
-	// we grab the plane equations of the six clipplanes of the viewfrustum
-	Matrix4x4 matViewing, matProjectionView;
-
-	GetModelViewMatrix(matViewing);
-	GetProjectionMatrix(matProjectionView);
-
-	matProjectionView = matViewing * matProjectionView;
-
-	frustum = Frustum(matProjectionView);
-
-
-	////////////
-	//-- normalize the coefficients
-
-	for (int i = 0; i < 6; ++ i)
-	{
-		// the clipping planes look outward the frustum,
-		// so distances > 0 mean that a point is outside
-		const float invLength = -1.0f / Magnitude(frustum.mClipPlanes[i].mNormal);
-	
-		frustum.mClipPlanes[i].mD *= invLength;
-		frustum.mClipPlanes[i].mNormal *= invLength;
-	}
-}
-
-
-void Camera::SetupViewProjection()
-{
-	glMatrixMode(GL_PROJECTION);
-	SetupProjection();
-
-	glMatrixMode(GL_MODELVIEW);
-	// set up the view matrix
-	SetupCameraView();
-}
-
-
-void Camera::SetupProjection()
-{
-	glLoadIdentity();
-	gluPerspective(mFOVy * 180.0f / M_PI, mAspect, mNear, mFar);
-}
-
-
-void Camera::SetupCameraView()
-{
-	Matrix4x4 m;
-	GetModelViewMatrix(m);
-
-	glLoadMatrixf((float *)m.x);
-}
-
-
-
-void Camera::ComputePointsInternal(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
-								   Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
-								   const Vector3 &view, const Vector3 &right, const Vector3 &up,
-								   const Vector3 &pos,
-								   float farthestVisibleDistance) const
-{
-	const float z_near = mNear;
-	const float z_far = min(mFar, farthestVisibleDistance);
-
-	const float fov = mFOVy;
-
-	const float aspectRatio = GetAspect();
-
-	const float h_near = tan(fov * 0.5f) * z_near;
-	const float w_near = h_near * aspectRatio;
-
-	const float h_far = tan(fov * 0.5f) * z_far;
-	const float w_far = h_far * aspectRatio;
-
-	const Vector3 fc = pos + view * z_far; 
-	
-
-	Vector3 t1, t2;
-
-	t1 = h_far * up;
-	t2 = w_far * right;
-
-	ftl = fc + t1 - t2;
-	ftr = fc + t1 + t2;
-	fbl = fc - t1 - t2;
-	fbr = fc - t1 + t2;
-
-	const Vector3 nc = pos + view * z_near;
-	
-	t1 = h_near * up;
-	t2 = w_near * right;
-
-	ntl = nc + t1 - t2;
-	ntr = nc + t1 + t2;
-	nbl = nc - t1 - t2;
-	nbr = nc - t1 + t2;
-}
-
-
-void Camera::ComputePoints(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
-						   Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
-						   float farthestVisibleDistance) const
-{
-	ComputePointsInternal(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr, 
-						  GetDirection(), GetRightVector(), GetUpVector(), GetPosition(),
-						  farthestVisibleDistance);
-}
-
-
-/*void Camera::SetOrtho(bool ortho)
-{
-	mIsOrtho = ortho;
-}*/
-
-
-void Camera::Yaw(float angle)
-{
-	mYaw += angle;
-	CalculateFromPitchAndYaw();
-}
-
-
-void Camera::Pitch(float angle)
-{
-	mPitch += angle;
-	CalculateFromPitchAndYaw();
-}
-
-
-void Camera::SetDirection(const Vector3 &dir)
-{
-	Vector3 ndir = -Normalize(dir);
-
-	mPitch = -atan2(ndir.x, ndir.y);
-	mYaw = atan2(ndir.z, sqrt((ndir.x * ndir.x) + (ndir.y * ndir.y)));
-
-	CalculateFromPitchAndYaw();
-}
-
-
-void Camera::CalculateFromPitchAndYaw()
-{
-	mViewOrientation = mBaseOrientation;
-
-	Matrix4x4 roty = RotationYMatrix(mPitch);
-	Matrix4x4 rotx = RotationXMatrix(mYaw);
-
-	mViewOrientation *= roty;
-	mViewOrientation *= rotx;
-}
-
-
-Vector3 Camera::GetDirection() const
-{ 
-	return -Vector3(mViewOrientation.x[0][2], mViewOrientation.x[1][2], mViewOrientation.x[2][2]);
-}
-
-
-Vector3 Camera::GetUpVector() const 
-{ 
-	return Vector3(mViewOrientation.x[0][1], mViewOrientation.x[1][1], mViewOrientation.x[2][1]);
-}
-
-
-Vector3 Camera::GetRightVector() const 
-{ 
-	return Vector3(mViewOrientation.x[0][0], mViewOrientation.x[1][0], mViewOrientation.x[2][0]);		
-}
-
-
-Vector3 Camera::GetBaseDirection() const
-{ 
-	return -Vector3(mBaseOrientation.x[0][2], mBaseOrientation.x[1][2], mBaseOrientation.x[2][2]);
-}
-
-
-Vector3 Camera::GetBaseUpVector() const 
-{ 
-	return Vector3(mBaseOrientation.x[0][1], mBaseOrientation.x[1][1], mBaseOrientation.x[2][1]);
-}
-
-
-Vector3 Camera::GetBaseRightVector() const 
-{ 
-	return Vector3(mBaseOrientation.x[0][0], mBaseOrientation.x[1][0], mBaseOrientation.x[2][0]);
-}
+
+/**********************************************************/
+/*            class Frustum implementation                */
+/**********************************************************/
 
 
@@ -312,8 +50,5 @@
 		Plane3 &plane = mClipPlanes[i];
 
-		//cout << "p" << i << " " << plane.mD  << endl;
-
 		VertexArray::const_iterator it, it_end = vertices.end();
-
 		float minDist = 1e20;
 
@@ -346,5 +81,214 @@
 
 
-Polyhedron *Camera::ComputeFrustum(float farthestVisibleDistance) const
+
+/*********************************************************/
+/*            class Camera implementation                */
+/*********************************************************/
+
+
+Camera::Camera() 
+{
+	SetPosition(Vector3(0, 0, 0));
+
+	mPitch = mYaw = 0;
+	Precompute(baseDir);
+
+	CalculateFromPitchAndYaw();
+}
+
+
+void Camera::Precompute(const Vector3 &dir) 
+{
+	Vector3 up = Vector3::UNIT_Z();
+	
+	mBaseOrientation = LookAt(Vector3::ZERO(), dir, up);
+	mViewOrientation = mBaseOrientation;
+}
+
+
+void Camera::SetPosition(const Vector3 &pos) 
+{
+	mPosition = pos;
+}
+
+
+void Camera::SetNear(float nearDist) 
+{
+	mNear = nearDist;
+}
+
+
+void Camera::SetFar(float farDist) 
+{ 
+	mFar = farDist; 
+}
+
+
+void Camera::GetModelViewMatrix(Matrix4x4 &mat) const
+{
+	mat = mViewOrientation;
+
+	// note: left handed system => we go into positive z
+	mat.x[3][0] = -DotProd(GetRightVector(), mPosition);
+	mat.x[3][1] = -DotProd(GetUpVector(), mPosition);
+	mat.x[3][2] = DotProd(GetDirection(), mPosition);
+}
+
+
+void Camera::GetViewOrientationMatrix(Matrix4x4 &mat) const
+{
+	mat = mViewOrientation;
+}
+
+
+void Camera::SetupViewProjection()
+{
+	glMatrixMode(GL_PROJECTION);
+	SetupProjection();
+
+	glMatrixMode(GL_MODELVIEW);
+	// set up the view matrix
+	SetupCameraView();
+}
+
+
+void Camera::SetupProjection()
+{
+	Matrix4x4 m;
+
+	GetProjectionMatrix(m);
+	glLoadMatrixf((float *)m.x);
+}
+
+
+void Camera::SetupCameraView()
+{
+	Matrix4x4 m;
+	GetModelViewMatrix(m);
+
+	glLoadMatrixf((float *)m.x);
+}
+
+
+void Camera::Yaw(float angle)
+{
+	mYaw += angle;
+	CalculateFromPitchAndYaw();
+}
+
+
+void Camera::Pitch(float angle)
+{
+	mPitch += angle;
+	CalculateFromPitchAndYaw();
+}
+
+
+void Camera::SetDirection(const Vector3 &dir)
+{
+	Vector3 ndir = -Normalize(dir);
+
+	mPitch = -atan2(ndir.x, ndir.y);
+	mYaw = atan2(ndir.z, sqrt((ndir.x * ndir.x) + (ndir.y * ndir.y)));
+
+	CalculateFromPitchAndYaw();
+}
+
+
+void Camera::CalculateFromPitchAndYaw()
+{
+	mViewOrientation = mBaseOrientation;
+
+	Matrix4x4 roty = RotationYMatrix(mPitch);
+	Matrix4x4 rotx = RotationXMatrix(mYaw);
+
+	mViewOrientation *= roty;
+	mViewOrientation *= rotx;
+}
+
+
+Vector3 Camera::GetDirection() const
+{ 
+	return -Vector3(mViewOrientation.x[0][2], mViewOrientation.x[1][2], mViewOrientation.x[2][2]);
+}
+
+
+Vector3 Camera::GetUpVector() const 
+{ 
+	return Vector3(mViewOrientation.x[0][1], mViewOrientation.x[1][1], mViewOrientation.x[2][1]);
+}
+
+
+Vector3 Camera::GetRightVector() const 
+{ 
+	return Vector3(mViewOrientation.x[0][0], mViewOrientation.x[1][0], mViewOrientation.x[2][0]);		
+}
+
+
+Vector3 Camera::GetBaseDirection() const
+{ 
+	return -Vector3(mBaseOrientation.x[0][2], mBaseOrientation.x[1][2], mBaseOrientation.x[2][2]);
+}
+
+
+Vector3 Camera::GetBaseUpVector() const 
+{ 
+	return Vector3(mBaseOrientation.x[0][1], mBaseOrientation.x[1][1], mBaseOrientation.x[2][1]);
+}
+
+
+Vector3 Camera::GetBaseRightVector() const 
+{ 
+	return Vector3(mBaseOrientation.x[0][0], mBaseOrientation.x[1][0], mBaseOrientation.x[2][0]);
+}
+
+
+void Camera::CalcFrustum(Frustum &frustum)
+{
+	// we grab the plane equations of the six clipplanes of the viewfrustum
+	Matrix4x4 matViewing, matProjectionView;
+
+	GetModelViewMatrix(matViewing);
+	GetProjectionMatrix(matProjectionView);
+
+	matProjectionView = matViewing * matProjectionView;
+
+	frustum = Frustum(matProjectionView);
+
+
+	////////////
+	//-- normalize the coefficients
+
+	for (int i = 0; i < 6; ++ i)
+	{
+		// the clipping planes look outward the frustum,
+		// so distances > 0 mean that a point is outside
+		const float invLength = -1.0f / Magnitude(frustum.mClipPlanes[i].mNormal);
+	
+		frustum.mClipPlanes[i].mD *= invLength;
+		frustum.mClipPlanes[i].mNormal *= invLength;
+	}
+}
+
+
+/*********************************************************/
+/*       Class PerspectiveCamera implementation           */
+/*********************************************************/
+
+
+PerspectiveCamera::PerspectiveCamera() 
+{
+	mFOVy = 60.0f * M_PI / 180.0f;
+}
+
+
+PerspectiveCamera::PerspectiveCamera(float aspect, float fieldOfView) 
+{
+	mFOVy = fieldOfView * M_PI / 180.0f;
+	mAspect = aspect;
+}
+
+
+Polyhedron *PerspectiveCamera::ComputeFrustum(float farthestVisibleDistance) const
 {
 	Vector3 ftl, ftr, fbl, fbr;
@@ -384,3 +328,71 @@
 
 
-}
+void PerspectiveCamera::ComputePointsInternal(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
+											  Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
+											  const Vector3 &view, const Vector3 &right, const Vector3 &up,
+											  const Vector3 &pos,
+											  float farthestVisibleDistance) const
+{
+	const float z_near = mNear;
+	const float z_far = min(mFar, farthestVisibleDistance);
+
+	const float fov = mFOVy;
+
+	const float aspectRatio = GetAspect();
+
+	const float h_near = tan(fov * 0.5f) * z_near;
+	const float w_near = h_near * aspectRatio;
+
+	const float h_far = tan(fov * 0.5f) * z_far;
+	const float w_far = h_far * aspectRatio;
+
+	const Vector3 fc = pos + view * z_far; 
+	
+
+	Vector3 t1, t2;
+
+	t1 = h_far * up;
+	t2 = w_far * right;
+
+	ftl = fc + t1 - t2;
+	ftr = fc + t1 + t2;
+	fbl = fc - t1 - t2;
+	fbr = fc - t1 + t2;
+
+	const Vector3 nc = pos + view * z_near;
+	
+	t1 = h_near * up;
+	t2 = w_near * right;
+
+	ntl = nc + t1 - t2;
+	ntr = nc + t1 + t2;
+	nbl = nc - t1 - t2;
+	nbr = nc - t1 + t2;
+}
+
+
+void PerspectiveCamera::ComputePoints(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
+									  Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
+									  float farthestVisibleDistance) const
+{
+	ComputePointsInternal(ftl, ftr, fbl, fbr, 
+		                  ntl, ntr, nbl, nbr, 
+						  GetDirection(), GetRightVector(), GetUpVector(), 
+						  GetPosition(),
+						  farthestVisibleDistance);
+}
+
+
+void PerspectiveCamera::GetProjectionMatrix(Matrix4x4 &mat) const
+{
+	mat = GetPerspective(mFOVy, 1.0f / mAspect, mNear, mFar);
+
+	Matrix4x4 mat2;
+	glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat2.x);
+
+	cout << "my projview:\n" << mat  << endl;
+	cout << "gl projview:\n" << mat2 << endl;
+}
+
+
+}
