Browse Source

Orthographic and perspective camera projections.

vectorfields
Vladimír Vondruš 16 years ago
parent
commit
9b6f3582e3
  1. 35
      src/Camera.cpp
  2. 21
      src/Camera.h
  3. 1
      src/Test/CMakeLists.txt
  4. 53
      src/Test/CameraTest.cpp
  5. 32
      src/Test/CameraTest.h

35
src/Camera.cpp

@ -18,6 +18,41 @@
namespace Magnum {
Camera::Camera(AbstractObject* parent): AbstractObject(parent), viewportWidth(0), viewportHeight(0), _aspectRatioPolicy(Extend) {
setOrthographic(2, 1, 1000);
}
void Camera::setOrthographic(GLfloat size, GLfloat near, GLfloat far) {
/* Scale the volume down so it fits in (-1, 1) in all directions */
GLfloat xyScale = 2/size;
GLfloat zScale = 2/(far-near);
rawProjectionMatrix = Matrix4::scaling(xyScale, xyScale, -zScale);
/* Move the volume on z into (-1, 1) range */
rawProjectionMatrix = Matrix4::translation(0, 0, -1-near*zScale)*rawProjectionMatrix;
fixAspectRatio();
}
void Camera::setPerspective(GLfloat fov, GLfloat near, GLfloat far) {
/* First move the volume on z in (-1, 1) range */
rawProjectionMatrix = Matrix4::translation(0, 0, 2*far*near/(far+near));
/* Then apply magic perspective matrix (with reversed Z) */
static GLfloat a[] = { 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, -1, -1,
0, 0, 0, 0 };
rawProjectionMatrix = Matrix4(a)*rawProjectionMatrix;
/* Then scale the volume down so it fits in (-1, 1) in all directions */
GLfloat xyScale = 1/tan(fov/2);
GLfloat zScale = 1+2*near/(far-near);
rawProjectionMatrix = Matrix4::scaling(xyScale, xyScale, zScale)*rawProjectionMatrix;
/* And... another magic */
rawProjectionMatrix.set(3, 3, 0);
fixAspectRatio();
}
Matrix4 Camera::cameraMatrix() const {

21
src/Camera.h

@ -40,6 +40,8 @@ class Camera: public AbstractObject {
/**
* @brief Constructor
* @param parent Parent object
*
* Calls <tt>setOrthographic(2, 1, 1000)</tt>.
*/
Camera(AbstractObject* parent = 0);
@ -49,6 +51,25 @@ class Camera: public AbstractObject {
/** @brief Set aspect ratio policy */
void setAspectRatioPolicy(AspectRatioPolicy policy) { _aspectRatioPolicy = policy; }
/**
* @brief Set orthographic projection
* @param size Size of (square) view
* @param near Near clipping plane
* @param far Far clipping plane
*
* The volume of given size will be scaled down to range (-1, 1) on all
* directions.
*/
void setOrthographic(GLfloat size, GLfloat near, GLfloat far);
/**
* @brief Set perspective projection
* @param fov Field of view angle
* @param near Near clipping plane
* @param far Far clipping plane
*/
void setPerspective(GLfloat fov, GLfloat near, GLfloat far);
/**
* @brief Camera matrix
*

1
src/Test/CMakeLists.txt

@ -1 +1,2 @@
magnum_add_test(AbstractObjectTest AbstractObjectTest.h AbstractObjectTest.cpp Magnum)
magnum_add_test(CameraTest CameraTest.h CameraTest.cpp Magnum)

53
src/Test/CameraTest.cpp

@ -0,0 +1,53 @@
/*
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "CameraTest.h"
#include "Camera.h"
#include <QtTest/QTest>
QTEST_APPLESS_MAIN(Magnum::Test::CameraTest)
namespace Magnum { namespace Test {
void CameraTest::orthographic() {
Camera camera;
camera.setOrthographic(5, 1, 9);
GLfloat a[] = {
0.4f, 0, 0, 0,
0, 0.4f, 0, 0,
0, 0, -0.25f, 0,
0, 0, -1.25f, 1
};
QVERIFY(camera.projectionMatrix() == a);
}
void CameraTest::perspective() {
Camera camera;
camera.setPerspective(27*PI/180, 32.0f, 100);
GLfloat a[] = {
4.1652994f, 0, 0, 0,
0, 4.1652994f, 0, 0,
0, 0, -1.9411764f, -1,
0, 0, -94.1176452f, 0
};
QVERIFY(camera.projectionMatrix() == Matrix4(a));
}
}}

32
src/Test/CameraTest.h

@ -0,0 +1,32 @@
#ifndef Magnum_CameraTest_h
#define Magnum_CameraTest_h
/*
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include <QtCore/QObject>
namespace Magnum { namespace Test {
class CameraTest: public QObject {
Q_OBJECT
private slots:
void orthographic();
void perspective();
};
}}
#endif
Loading…
Cancel
Save