Working on support for off-axis projection.

This commit is contained in:
Andrzej Kapolka 2013-05-17 10:17:21 -07:00
parent a23ed58a53
commit 3ed99f40a6
7 changed files with 103 additions and 12 deletions

View file

@ -447,7 +447,12 @@ void Application::resizeGL(int width, int height) {
}
// On window reshape, we need to tell OpenGL about our new setting
gluPerspective(fov,aspectRatio,nearClip,farClip);
float left, right, bottom, top, nearVal, farVal;
glm::vec3 eyeOffset = camera.getEyeOffsetPosition();
computeOffsetFrustum(fov, aspectRatio, nearClip, farClip, eyeOffset.x, eyeOffset.y, eyeOffset.z,
left, right, bottom, top, nearVal, farVal);
glFrustum(left, right, bottom, top, nearVal, farVal);
glTranslatef(-eyeOffset.x, -eyeOffset.y, -eyeOffset.z);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@ -542,9 +547,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
_audio.startEchoTest();
break;
case Qt::Key_L:
_displayLevels = !_displayLevels;
break;
//case Qt::Key_L:
// _displayLevels = !_displayLevels;
// break;
case Qt::Key_E:
_myAvatar.setDriveKeys(UP, 1);
@ -598,6 +603,36 @@ void Application::keyPressEvent(QKeyEvent* event) {
_myAvatar.setDriveKeys(shifted ? RIGHT : ROT_RIGHT, 1);
break;
case Qt::Key_I:
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0, 0.001, 0));
resizeGL(_glWidget->width(), _glWidget->height());
break;
case Qt::Key_K:
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0, -0.001, 0));
resizeGL(_glWidget->width(), _glWidget->height());
break;
case Qt::Key_J:
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0));
resizeGL(_glWidget->width(), _glWidget->height());
break;
case Qt::Key_L:
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0.001, 0, 0));
resizeGL(_glWidget->width(), _glWidget->height());
break;
case Qt::Key_U:
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0, 0, 0.001));
resizeGL(_glWidget->width(), _glWidget->height());
break;
case Qt::Key_Y:
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0, 0, -0.001));
resizeGL(_glWidget->width(), _glWidget->height());
break;
default:
event->ignore();
break;
@ -1412,6 +1447,8 @@ void Application::loadViewFrustum(ViewFrustum& viewFrustum) {
viewFrustum.setFieldOfView(fov);
viewFrustum.setNearClip(nearClip);
viewFrustum.setFarClip(farClip);
viewFrustum.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition());
viewFrustum.setEyeOffsetOrientation(_myCamera.getEyeOffsetOrientation());
// Ask the ViewFrustum class to calculate our corners
viewFrustum.calculate();

View file

@ -153,6 +153,16 @@ void Camera::setFarClip (float f) {
_frustumNeedsReshape = true;
}
void Camera::setEyeOffsetPosition (const glm::vec3& p) {
_eyeOffsetPosition = p;
_frustumNeedsReshape = true;
}
void Camera::setEyeOffsetOrientation (const glm::quat& o) {
_eyeOffsetOrientation = o;
_frustumNeedsReshape = true;
}
void Camera::initialize() {
_needsToInitialize = true;
}

View file

@ -10,6 +10,7 @@
#include "Orientation.h"
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
enum CameraMode
{
@ -53,6 +54,8 @@ public:
void setAspectRatio ( float a );
void setNearClip ( float n );
void setFarClip ( float f );
void setEyeOffsetPosition ( const glm::vec3& p);
void setEyeOffsetOrientation ( const glm::quat& o);
float getYaw () { return _yaw; }
float getPitch () { return _pitch; }
@ -64,6 +67,8 @@ public:
float getAspectRatio() { return _aspectRatio; }
float getNearClip () { return _nearClip; }
float getFarClip () { return _farClip; }
glm::vec3 getEyeOffsetPosition () { return _eyeOffsetPosition; }
glm::quat getEyeOffsetOrientation () { return _eyeOffsetOrientation; }
bool getFrustumNeedsReshape(); // call to find out if the view frustum needs to be reshaped
void setFrustumWasReshaped(); // call this after reshaping the view frustum.
@ -79,6 +84,8 @@ private:
float _aspectRatio;
float _nearClip;
float _farClip;
glm::vec3 _eyeOffsetPosition;
glm::quat _eyeOffsetOrientation;
float _yaw;
float _pitch;
float _roll;

View file

@ -409,3 +409,18 @@ int insertIntoSortedArrays(void* value, float key, int originalIndex,
return -1; // error case
}
// Takes a set of perspective parameters (as one would pass to gluPerspective) and an eye offset (in view space) and writes
// out the parameters to pass to glFrustum to effect the possibly skewed view frustum
void computeOffsetFrustum(float fovy, float aspect, float zNear, float zFar, float xOffset, float yOffset, float zOffset,
float& left, float& right, float& bottom, float& top, float& nearVal, float& farVal) {
// adjust near and far distances by z offset
nearVal = zNear + zOffset;
farVal = zFar + zOffset;
float hheight = zNear * tanf(fovy * 0.5f * PI_OVER_180);
top = hheight - yOffset;
bottom = -hheight - yOffset;
float hwidth = aspect * hheight;
left = -hwidth - xOffset;
right = hwidth - xOffset;
}

View file

@ -78,4 +78,7 @@ int insertIntoSortedArrays(void* value, float key, int originalIndex,
void** valueArray, float* keyArray, int* originalIndexArray,
int currentCount, int maxCount);
void computeOffsetFrustum(float fovy, float aspect, float zNear, float zFar, float xOffset, float yOffset, float zOffset,
float& left, float& right, float& bottom, float& top, float& nearVal, float& farVal);
#endif /* defined(__hifi__SharedUtil__) */

View file

@ -9,6 +9,7 @@
//
#include "ViewFrustum.h"
#include "SharedUtil.h"
#include "voxels_Log.h"
using voxels_lib::printLog;
@ -52,6 +53,16 @@ void ViewFrustum::calculate() {
glm::vec3 front = _direction;
float left, right, bottom, top, nearVal, farVal;
computeOffsetFrustum(_fieldOfView, _aspectRatio, _nearClip, _farClip,
_eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z,
left, right, bottom, top, nearVal, farVal);
_nearHeight = top - bottom;
_nearWidth = right - left;
_farHeight = _nearHeight * (farVal / nearVal);
_farWidth = _nearWidth * (farVal / nearVal);
// Calculating field of view.
float fovInRadians = _fieldOfView * PI_OVER_180;

View file

@ -12,6 +12,7 @@
#define __hifi__ViewFrustum__
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include "Plane.h"
#include "AABox.h"
@ -29,6 +30,8 @@ private:
float _aspectRatio;
float _nearClip;
float _farClip;
glm::vec3 _eyeOffsetPosition;
glm::quat _eyeOffsetOrientation;
// Calculated values
float _nearHeight;
@ -63,16 +66,21 @@ public:
const glm::vec3& getRight() const { return _right; };
// setters for lens attributes
void setFieldOfView ( float f ) { _fieldOfView = f; }
void setAspectRatio ( float a ) { _aspectRatio = a; }
void setNearClip ( float n ) { _nearClip = n; }
void setFarClip ( float f ) { _farClip = f; }
void setFieldOfView ( float f ) { _fieldOfView = f; }
void setAspectRatio ( float a ) { _aspectRatio = a; }
void setNearClip ( float n ) { _nearClip = n; }
void setFarClip ( float f ) { _farClip = f; }
void setEyeOffsetPosition (const glm::vec3& p) { _eyeOffsetPosition = p; }
void setEyeOffsetOrientation (const glm::quat& o) { _eyeOffsetOrientation = o; }
// getters for lens attributes
float getFieldOfView() const { return _fieldOfView; };
float getAspectRatio() const { return _aspectRatio; };
float getNearClip() const { return _nearClip; };
float getFarClip() const { return _farClip; };
float getFieldOfView() const { return _fieldOfView; };
float getAspectRatio() const { return _aspectRatio; };
float getNearClip() const { return _nearClip; };
float getFarClip() const { return _farClip; };
const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; };
const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation;};
const glm::vec3& getFarCenter() const { return _farCenter; };
const glm::vec3& getFarTopLeft() const { return _farTopLeft; };