mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-24 04:41:53 +00:00
Refactor stereo 3d projection matrix calculations to use VSMatrix.
This commit is contained in:
parent
d603999ee3
commit
789dca2ab3
6 changed files with 19 additions and 43 deletions
|
@ -121,7 +121,7 @@ public:
|
|||
void Flush() {}
|
||||
|
||||
void SetProjection(float fov, float ratio, float fovratio);
|
||||
void SetProjection(FLOATTYPE matrix[4][4]); // raw matrix input from stereo 3d modes
|
||||
void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes
|
||||
void SetViewMatrix(fixed_t viewx, fixed_t viewy, fixed_t viewz, bool mirror, bool planemirror);
|
||||
void ProcessScene(bool toscreen = false);
|
||||
|
||||
|
|
|
@ -257,9 +257,10 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio)
|
|||
}
|
||||
|
||||
// raw matrix input from stereo 3d modes
|
||||
void FGLRenderer::SetProjection(FLOATTYPE matrix[4][4])
|
||||
void FGLRenderer::SetProjection(VSMatrix matrix)
|
||||
{
|
||||
gl_RenderState.mProjectionMatrix.loadMatrix(&matrix[0][0]);
|
||||
gl_RenderState.mProjectionMatrix.loadIdentity();
|
||||
gl_RenderState.mProjectionMatrix.multMatrix(matrix);
|
||||
gl_RenderState.Set2DMode(false);
|
||||
}
|
||||
|
||||
|
@ -812,7 +813,6 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
|||
retval = viewsector;
|
||||
|
||||
// Render (potentially) multiple views for stereo 3d
|
||||
FLOATTYPE projectionMatrix[4][4];
|
||||
float viewShift[3];
|
||||
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
|
||||
stereo3dMode.SetUp();
|
||||
|
@ -824,8 +824,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
|||
SetViewport(bounds);
|
||||
mCurrentFoV = fov;
|
||||
// Stereo mode specific perspective projection
|
||||
(*eye)->GetProjection(fov, ratio, fovratio, projectionMatrix);
|
||||
SetProjection(projectionMatrix);
|
||||
SetProjection( (*eye)->GetProjection(fov, ratio, fovratio) );
|
||||
// SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper
|
||||
SetViewAngle(viewangle);
|
||||
// Stereo mode specific viewpoint adjustment - temporarily shifts global viewx, viewy, viewz
|
||||
|
|
|
@ -6,29 +6,15 @@ namespace s3d {
|
|||
|
||||
|
||||
/* virtual */
|
||||
void EyePose::GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio, FLOATTYPE m[4][4]) const
|
||||
VSMatrix EyePose::GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio) const
|
||||
{
|
||||
VSMatrix result;
|
||||
|
||||
// Lifted from gl_scene.cpp FGLRenderer::SetProjection()
|
||||
double fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||
const FLOATTYPE zNear = 5.0;
|
||||
const FLOATTYPE zFar = 65536.0;
|
||||
float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||
result.perspective(fovy, aspectRatio, 5.f, 65536.f);
|
||||
|
||||
double radians = fovy / 2 * M_PI / 180;
|
||||
|
||||
FLOATTYPE deltaZ = zFar - zNear;
|
||||
double sine = sin(radians);
|
||||
if ((deltaZ == 0) || (sine == 0) || (aspectRatio == 0)) {
|
||||
return;
|
||||
}
|
||||
FLOATTYPE cotangent = FLOATTYPE(cos(radians) / sine);
|
||||
|
||||
memset(m, 0, 16*sizeof(FLOATTYPE));
|
||||
m[0][0] = cotangent / aspectRatio;
|
||||
m[1][1] = cotangent;
|
||||
m[2][2] = -(zFar + zNear) / deltaZ;
|
||||
m[2][3] = -1;
|
||||
m[3][2] = -2 * zNear * zFar / deltaZ;
|
||||
m[3][3] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
@ -24,7 +24,7 @@ class EyePose
|
|||
public:
|
||||
EyePose() {}
|
||||
virtual ~EyePose() {}
|
||||
virtual void GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio, FLOATTYPE outMatrix[4][4]) const;
|
||||
virtual VSMatrix GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio) const;
|
||||
virtual Viewport GetViewport(const Viewport& fullViewport) const;
|
||||
virtual void GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const;
|
||||
virtual void SetUp() const {};
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace s3d {
|
|||
|
||||
|
||||
/* virtual */
|
||||
void ShiftedEyePose::GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio, FLOATTYPE m[4][4]) const
|
||||
VSMatrix ShiftedEyePose::GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio) const
|
||||
{
|
||||
// Lifted from gl_scene.cpp FGLRenderer::SetProjection()
|
||||
FLOATTYPE fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||
|
@ -20,10 +20,10 @@ void ShiftedEyePose::GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTY
|
|||
|
||||
// For stereo 3D, use asymmetric frustum shift in projection matrix
|
||||
// Q: shouldn't shift vary with roll angle, at least for desktop display?
|
||||
// A: (lab) roll is not measured on desktop display (yet)
|
||||
// A: No. (lab) roll is not measured on desktop display (yet)
|
||||
double frustumShift = zNear * shift / vr_screendist; // meters cancel
|
||||
// double frustumShift = 0; // Turning off shift for debugging
|
||||
double fH = tan(fovy / 360 * M_PI) * zNear;
|
||||
double fH = tan(DEG2RAD(fovy/2)) * zNear;
|
||||
double fW = fH * aspectRatio;
|
||||
// Emulate glFrustum command:
|
||||
// glFrustum(-fW - frustumShift, fW - frustumShift, -fH, fH, zNear, zFar);
|
||||
|
@ -31,19 +31,10 @@ void ShiftedEyePose::GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTY
|
|||
double right = fW - frustumShift;
|
||||
double bottom = -fH;
|
||||
double top = fH;
|
||||
double deltaZ = zFar - zNear;
|
||||
|
||||
memset(m, 0, 16 * sizeof(FLOATTYPE)); // set all elements to zero, cleverly
|
||||
|
||||
// https://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml
|
||||
m[0][0] = 2 * zNear / (right - left);
|
||||
m[1][1] = 2 * zNear / (top - bottom);
|
||||
m[2][2] = -(zFar + zNear) / deltaZ;
|
||||
m[2][3] = -1;
|
||||
m[3][2] = -2 * zNear * zFar / deltaZ;
|
||||
// m[3][3] = 0; // redundant
|
||||
// m[2][1] = (top + bottom) / (top - bottom); // zero for the cases I know of...
|
||||
m[2][0] = (right + left) / (right - left); // asymmetric shift is in this term
|
||||
VSMatrix result(1);
|
||||
result.frustum(left, right, bottom, top, zNear, zFar);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ public:
|
|||
ShiftedEyePose(FLOATTYPE shift) : shift(shift) {};
|
||||
FLOATTYPE getShift() const { return shift; }
|
||||
void setShift(FLOATTYPE shift) { this->shift = shift; }
|
||||
virtual void GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio, FLOATTYPE outMatrix[4][4]) const;
|
||||
virtual VSMatrix GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio) const;
|
||||
virtual void GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const;
|
||||
protected:
|
||||
FLOATTYPE shift;
|
||||
|
|
Loading…
Reference in a new issue