mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-12 07:34:36 +00:00
Copy stereo3d source files from my GLOOME fork.
This commit is contained in:
parent
4e1723eeb7
commit
694dff67e4
10 changed files with 548 additions and 0 deletions
29
src/gl/stereo3d/gl_anaglyph.cpp
Normal file
29
src/gl/stereo3d/gl_anaglyph.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#include "gl_anaglyph.h"
|
||||||
|
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
MaskAnaglyph::MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters)
|
||||||
|
: leftEye(leftColorMask, ipdMeters), rightEye(leftColorMask.inverse(), ipdMeters)
|
||||||
|
{
|
||||||
|
eye_ptrs.push_back(&leftEye);
|
||||||
|
eye_ptrs.push_back(&rightEye);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
||||||
|
{
|
||||||
|
static GreenMagenta instance(ipd);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
const RedCyan& RedCyan::getInstance(float ipd)
|
||||||
|
{
|
||||||
|
static RedCyan instance(ipd);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace s3d */
|
75
src/gl/stereo3d/gl_anaglyph.h
Normal file
75
src/gl/stereo3d/gl_anaglyph.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
#ifndef GL_ANAGLYPH_H_
|
||||||
|
#define GL_ANAGLYPH_H_
|
||||||
|
|
||||||
|
#include "gl_stereo3d.h"
|
||||||
|
#include "gl_stereo_leftright.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
|
||||||
|
class ColorMask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ColorMask(bool r, bool g, bool b) : r(r), g(g), b(b) {}
|
||||||
|
ColorMask inverse() const { return ColorMask(!r, !g, !b); }
|
||||||
|
|
||||||
|
GLboolean r;
|
||||||
|
GLboolean g;
|
||||||
|
GLboolean b;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AnaglyphLeftPose : public LeftEyePose
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnaglyphLeftPose(const ColorMask& colorMask, float ipd) : LeftEyePose(ipd), colorMask(colorMask) {}
|
||||||
|
virtual void SetUp() const { glColorMask(colorMask.r, colorMask.g, colorMask.b, true); }
|
||||||
|
virtual void TearDown() const { glColorMask(1,1,1,1); }
|
||||||
|
private:
|
||||||
|
ColorMask colorMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AnaglyphRightPose : public RightEyePose
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnaglyphRightPose(const ColorMask& colorMask, float ipd) : RightEyePose(ipd), colorMask(colorMask) {}
|
||||||
|
virtual void SetUp() const { glColorMask(colorMask.r, colorMask.g, colorMask.b, true); }
|
||||||
|
virtual void TearDown() const { glColorMask(1,1,1,1); }
|
||||||
|
private:
|
||||||
|
ColorMask colorMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MaskAnaglyph : public Stereo3DMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters);
|
||||||
|
private:
|
||||||
|
AnaglyphLeftPose leftEye;
|
||||||
|
AnaglyphRightPose rightEye;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RedCyan : public MaskAnaglyph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const RedCyan& getInstance(float ipd);
|
||||||
|
|
||||||
|
RedCyan(float ipd) : MaskAnaglyph(ColorMask(true, false, false), ipd) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GreenMagenta : public MaskAnaglyph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const GreenMagenta& getInstance(float ipd);
|
||||||
|
|
||||||
|
GreenMagenta(float ipd) : MaskAnaglyph(ColorMask(false, true, false), ipd) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO matrix anaglyph
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace st3d */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* GL_ANAGLYPH_H_ */
|
71
src/gl/stereo3d/gl_stereo3d.cpp
Normal file
71
src/gl/stereo3d/gl_stereo3d.cpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#include "gl/stereo3d/gl_stereo3d.h"
|
||||||
|
#include "vectors.h" // RAD2DEG
|
||||||
|
#include "doomtype.h" // M_PI
|
||||||
|
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
|
||||||
|
/* virtual */
|
||||||
|
void EyePose::GetProjection(float fov, float aspectRatio, float fovRatio, GLdouble m[4][4]) const
|
||||||
|
{
|
||||||
|
// Lifted from gl_scene.cpp FGLRenderer::SetProjection()
|
||||||
|
float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||||
|
const double zNear = 5.0;
|
||||||
|
const double zFar = 65536.0;
|
||||||
|
|
||||||
|
double sine, cotangent, deltaZ;
|
||||||
|
double radians = fovy / 2 * M_PI / 180;
|
||||||
|
|
||||||
|
deltaZ = zFar - zNear;
|
||||||
|
sine = sin(radians);
|
||||||
|
if ((deltaZ == 0) || (sine == 0) || (aspectRatio == 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cotangent = cos(radians) / sine;
|
||||||
|
|
||||||
|
memset(m, 0, 16*sizeof(GLdouble));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* virtual */
|
||||||
|
Viewport EyePose::GetViewport(const Viewport& fullViewport) const
|
||||||
|
{
|
||||||
|
return fullViewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* virtual */
|
||||||
|
void EyePose::GetViewShift(float yaw, float outViewShift[3]) const
|
||||||
|
{
|
||||||
|
// pass-through for Mono view
|
||||||
|
outViewShift[0] = 0;
|
||||||
|
outViewShift[1] = 0;
|
||||||
|
outViewShift[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Stereo3DMode::Stereo3DMode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Stereo3DMode::~Stereo3DMode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid static initialization order fiasco by declaring first Mode type (Mono) here in the
|
||||||
|
// same source file as Stereo3DMode::getCurrentMode()
|
||||||
|
// https://isocpp.org/wiki/faq/ctors#static-init-order
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
const MonoView& MonoView::getInstance()
|
||||||
|
{
|
||||||
|
static MonoView instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace s3d */
|
80
src/gl/stereo3d/gl_stereo3d.h
Normal file
80
src/gl/stereo3d/gl_stereo3d.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#ifndef GL_STEREO3D_H_
|
||||||
|
#define GL_STEREO3D_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "gl/system/gl_system.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* stereoscopic 3D API */
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
|
||||||
|
/* Subregion of current display window */
|
||||||
|
class Viewport
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int x, y;
|
||||||
|
int width, height;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Viewpoint of one eye */
|
||||||
|
class EyePose
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EyePose() {}
|
||||||
|
virtual ~EyePose() {}
|
||||||
|
virtual void GetProjection(float fov, float aspectRatio, float fovRatio, GLdouble outMatrix[4][4]) const;
|
||||||
|
virtual Viewport GetViewport(const Viewport& fullViewport) const;
|
||||||
|
virtual void GetViewShift(float yaw, float outViewShift[3]) const;
|
||||||
|
virtual void SetUp() const {};
|
||||||
|
virtual void TearDown() const {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Base class for stereoscopic 3D rendering modes */
|
||||||
|
class Stereo3DMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* const_iterator cycles through the various eye viewpoints */
|
||||||
|
typedef std::vector<const EyePose *>::const_iterator const_iterator;
|
||||||
|
|
||||||
|
/* static methods for managing the selected stereoscopic view state */
|
||||||
|
static const Stereo3DMode& getCurrentMode();
|
||||||
|
|
||||||
|
Stereo3DMode();
|
||||||
|
virtual ~Stereo3DMode();
|
||||||
|
/* const_iterator cycles through the various eye viewpoints */
|
||||||
|
virtual const_iterator begin() const { return eye_ptrs.begin(); }
|
||||||
|
virtual const_iterator end() const { return eye_ptrs.end(); }
|
||||||
|
/* hooks for setup and cleanup operations for each stereo mode */
|
||||||
|
virtual void SetUp() const {};
|
||||||
|
virtual void TearDown() const {};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<const EyePose *> eye_ptrs;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Stereo3DMode const * currentStereo3DMode;
|
||||||
|
static void setCurrentMode(const Stereo3DMode& mode);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ordinary non-3D rendering
|
||||||
|
*/
|
||||||
|
class MonoView : public Stereo3DMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const MonoView& getInstance();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MonoView() { eye_ptrs.push_back(¢ralEye); }
|
||||||
|
EyePose centralEye;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace st3d */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* GL_STEREO3D_H_ */
|
51
src/gl/stereo3d/gl_stereo_cvars.cpp
Normal file
51
src/gl/stereo3d/gl_stereo_cvars.cpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#include "gl/stereo3d/gl_stereo3d.h"
|
||||||
|
#include "gl/stereo3d/gl_stereo_leftright.h"
|
||||||
|
#include "gl/stereo3d/gl_anaglyph.h"
|
||||||
|
#include "gl/system/gl_cvars.h"
|
||||||
|
|
||||||
|
// Set up 3D-specific console variables:
|
||||||
|
CVAR(Int, vr_mode, 0, CVAR_GLOBALCONFIG)
|
||||||
|
// intraocular distance in meters
|
||||||
|
CVAR(Float, vr_ipd, 0.062f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // METERS
|
||||||
|
CVAR(Float, vr_screendist, 0.80f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // METERS
|
||||||
|
CVAR(Float, vr_hunits_per_meter, 41.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // METERS
|
||||||
|
|
||||||
|
// Manage changing of 3D modes:
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
// Initialize static member
|
||||||
|
Stereo3DMode const * Stereo3DMode::currentStereo3DMode = nullptr;
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void Stereo3DMode::setCurrentMode(const Stereo3DMode& mode) {
|
||||||
|
Stereo3DMode::currentStereo3DMode = &mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
||||||
|
{
|
||||||
|
// NOTE: Ensure that these vr_mode values correspond to the ones in wadsrc/static/menudef.z
|
||||||
|
switch (vr_mode)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
setCurrentMode(GreenMagenta::getInstance(vr_ipd));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
setCurrentMode(RedCyan::getInstance(vr_ipd));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
setCurrentMode(LeftEyeView::getInstance(vr_ipd));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
setCurrentMode(RightEyeView::getInstance(vr_ipd));
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
setCurrentMode(MonoView::getInstance());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *currentStereo3DMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace s3d */
|
||||||
|
|
79
src/gl/stereo3d/gl_stereo_leftright.cpp
Normal file
79
src/gl/stereo3d/gl_stereo_leftright.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include "gl_stereo_leftright.h"
|
||||||
|
#include "vectors.h" // RAD2DEG
|
||||||
|
#include "doomtype.h" // M_PI
|
||||||
|
#include "gl/system/gl_cvars.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
EXTERN_CVAR(Float, vr_screendist)
|
||||||
|
EXTERN_CVAR(Float, vr_hunits_per_meter)
|
||||||
|
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
|
||||||
|
/* virtual */
|
||||||
|
void ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRatio, GLdouble m[4][4]) const
|
||||||
|
{
|
||||||
|
// Lifted from gl_scene.cpp FGLRenderer::SetProjection()
|
||||||
|
float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||||
|
double zNear = 5.0;
|
||||||
|
double zFar = 65536.0;
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
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 fW = fH * aspectRatio;
|
||||||
|
// Emulate glFrustum command:
|
||||||
|
// glFrustum(-fW - frustumShift, fW - frustumShift, -fH, fH, zNear, zFar);
|
||||||
|
double left = -fW - frustumShift;
|
||||||
|
double right = fW - frustumShift;
|
||||||
|
double bottom = -fH;
|
||||||
|
double top = fH;
|
||||||
|
double deltaZ = zFar - zNear;
|
||||||
|
|
||||||
|
memset(m, 0, 16 * sizeof(GLdouble)); // 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* virtual */
|
||||||
|
void ShiftedEyePose::GetViewShift(float yaw, float outViewShift[3]) const
|
||||||
|
{
|
||||||
|
float dx = cos(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
||||||
|
float dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
||||||
|
outViewShift[0] = dx;
|
||||||
|
outViewShift[1] = dy;
|
||||||
|
outViewShift[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
||||||
|
{
|
||||||
|
static LeftEyeView instance(ipd);
|
||||||
|
instance.setIpd(ipd);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||||
|
{
|
||||||
|
static RightEyeView instance(ipd);
|
||||||
|
instance.setIpd(ipd);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace s3d */
|
71
src/gl/stereo3d/gl_stereo_leftright.h
Normal file
71
src/gl/stereo3d/gl_stereo_leftright.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#ifndef GL_STEREO_LEFTRIGHT_H_
|
||||||
|
#define GL_STEREO_LEFTRIGHT_H_
|
||||||
|
|
||||||
|
#include "gl_stereo3d.h"
|
||||||
|
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
|
||||||
|
class ShiftedEyePose : public EyePose
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShiftedEyePose(float shift) : shift(shift) {};
|
||||||
|
float getShift() const { return shift; }
|
||||||
|
void setShift(float shift) { this->shift = shift; }
|
||||||
|
virtual void GetProjection(float fov, float aspectRatio, float fovRatio, GLdouble outMatrix[4][4]) const;
|
||||||
|
virtual void GetViewShift(float yaw, float outViewShift[3]) const;
|
||||||
|
protected:
|
||||||
|
float shift;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LeftEyePose : public ShiftedEyePose
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LeftEyePose(float ipd) : ShiftedEyePose(-0.5*ipd) {}
|
||||||
|
float getIpd() const { return -2.0*getShift(); }
|
||||||
|
void setIpd(float ipd) { setShift(-0.5*ipd); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RightEyePose : public ShiftedEyePose
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RightEyePose(float ipd) : ShiftedEyePose(+0.5*ipd) {}
|
||||||
|
float getIpd() const { return +2.0*shift; }
|
||||||
|
void setIpd(float ipd) { setShift(+0.5*ipd); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As if viewed through the left eye only
|
||||||
|
*/
|
||||||
|
class LeftEyeView : public Stereo3DMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const LeftEyeView& getInstance(float ipd);
|
||||||
|
|
||||||
|
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
||||||
|
float getIpd() const { return eye.getIpd(); }
|
||||||
|
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||||
|
protected:
|
||||||
|
LeftEyePose eye;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RightEyeView : public Stereo3DMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const RightEyeView& getInstance(float ipd);
|
||||||
|
|
||||||
|
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
||||||
|
float getIpd() const { return eye.getIpd(); }
|
||||||
|
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||||
|
protected:
|
||||||
|
RightEyePose eye;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace s3d */
|
||||||
|
|
||||||
|
#endif /* GL_STEREO_LEFTRIGHT_H_ */
|
38
src/gl/stereo3d/scoped_color_mask.h
Normal file
38
src/gl/stereo3d/scoped_color_mask.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef GL_STEREO3D_SCOPED_COLOR_MASK_H_
|
||||||
|
#define GL_STEREO3D_SCOPED_COLOR_MASK_H_
|
||||||
|
|
||||||
|
#include "gl/glew.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporarily change color mask
|
||||||
|
*/
|
||||||
|
class ScopedColorMask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScopedColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a)
|
||||||
|
: isPushed(false)
|
||||||
|
{
|
||||||
|
setColorMask(r, g, b, a);
|
||||||
|
}
|
||||||
|
~ScopedColorMask() {
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
void setColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
|
||||||
|
if (!isPushed) {
|
||||||
|
glPushAttrib(GL_COLOR_BUFFER_BIT);
|
||||||
|
isPushed = true;
|
||||||
|
}
|
||||||
|
glColorMask(r, g, b, a);
|
||||||
|
}
|
||||||
|
void revert() {
|
||||||
|
if (isPushed) {
|
||||||
|
glPopAttrib();
|
||||||
|
isPushed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool isPushed;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // GL_STEREO3D_SCOPED_COLOR_MASK_H_
|
29
src/gl/stereo3d/scoped_view_shifter.cpp
Normal file
29
src/gl/stereo3d/scoped_view_shifter.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#include "scoped_view_shifter.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
ScopedViewShifter::ScopedViewShifter(float dxyz[3]) // in meters
|
||||||
|
{
|
||||||
|
// save original values
|
||||||
|
cachedViewx = viewx;
|
||||||
|
cachedViewy = viewy;
|
||||||
|
cachedViewz = viewz;
|
||||||
|
// modify values
|
||||||
|
float fViewx = FIXED2FLOAT(viewx) - dxyz[0];
|
||||||
|
float fViewy = FIXED2FLOAT(viewy) + dxyz[1];
|
||||||
|
float fViewz = FIXED2FLOAT(viewz) + dxyz[2];
|
||||||
|
viewx = FLOAT2FIXED(fViewx);
|
||||||
|
viewy = FLOAT2FIXED(fViewy);
|
||||||
|
viewz = FLOAT2FIXED(fViewz);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopedViewShifter::~ScopedViewShifter()
|
||||||
|
{
|
||||||
|
// restore original values
|
||||||
|
viewx = cachedViewx;
|
||||||
|
viewy = cachedViewy;
|
||||||
|
viewz = cachedViewz;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
src/gl/stereo3d/scoped_view_shifter.h
Normal file
25
src/gl/stereo3d/scoped_view_shifter.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef GL_STEREO3D_SCOPED_VIEW_SHIFTER_H_
|
||||||
|
#define GL_STEREO3D_SCOPED_VIEW_SHIFTER_H_
|
||||||
|
|
||||||
|
#include "basictypes.h"
|
||||||
|
|
||||||
|
namespace s3d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporarily shift viewx, viewy, viewz
|
||||||
|
*/
|
||||||
|
class ScopedViewShifter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScopedViewShifter(float dxyz[3]); // in meters
|
||||||
|
~ScopedViewShifter();
|
||||||
|
|
||||||
|
private:
|
||||||
|
fixed_t cachedViewx;
|
||||||
|
fixed_t cachedViewy;
|
||||||
|
fixed_t cachedViewz;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace s3d */
|
||||||
|
|
||||||
|
#endif // GL_STEREO3D_SCOPED_VIEW_SHIFTER_H_
|
Loading…
Reference in a new issue