mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-21 19:51:27 +00:00
Initial implementation of five 3D modes -- some bugs remain.
This commit is contained in:
parent
694dff67e4
commit
0874455faf
16 changed files with 219 additions and 172 deletions
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.cpp text
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -40,3 +40,4 @@
|
|||
/zlib/x64/
|
||||
/build_vc2013_64bit
|
||||
/build_vc2015
|
||||
/build_cmake
|
||||
|
|
|
@ -762,6 +762,7 @@ file( GLOB HEADER_FILES
|
|||
gl/models/*.h
|
||||
gl/renderer/*.h
|
||||
gl/scene/*.h
|
||||
gl/stereo3d/*.h
|
||||
gl/shaders/*.h
|
||||
gl/system/*.h
|
||||
gl/textures/*.h
|
||||
|
@ -1120,6 +1121,11 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
|||
gl/scene/gl_walls_draw.cpp
|
||||
gl/scene/gl_vertex.cpp
|
||||
gl/scene/gl_spritelight.cpp
|
||||
gl/stereo3d/gl_stereo3d.cpp
|
||||
gl/stereo3d/gl_stereo_cvars.cpp
|
||||
gl/stereo3d/gl_stereo_leftright.cpp
|
||||
gl/stereo3d/scoped_view_shifter.cpp
|
||||
gl/stereo3d/gl_anaglyph.cpp
|
||||
gl/dynlights/gl_dynlight.cpp
|
||||
gl/dynlights/gl_glow.cpp
|
||||
gl/dynlights/gl_dynlight1.cpp
|
||||
|
@ -1371,6 +1377,7 @@ source_group("OpenGL Renderer\\HQ Resize Assembly version" REGULAR_EXPRESSION "^
|
|||
source_group("OpenGL Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/models/.+")
|
||||
source_group("OpenGL Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/renderer/.+")
|
||||
source_group("OpenGL Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/scene/.+")
|
||||
source_group("OpenGL Renderer\\Stereo3D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/stereo3d/.+")
|
||||
source_group("OpenGL Renderer\\Shaders" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/shaders/.+")
|
||||
source_group("OpenGL Renderer\\System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/system/.+")
|
||||
source_group("OpenGL Renderer\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/textures/.+")
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "v_video.h"
|
||||
#include "vectors.h"
|
||||
#include "r_renderer.h"
|
||||
#include "gl/data/gl_matrix.h"
|
||||
|
||||
struct particle_t;
|
||||
class FCanvasTexture;
|
||||
|
@ -120,6 +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 SetViewMatrix(fixed_t viewx, fixed_t viewy, fixed_t viewz, bool mirror, bool planemirror);
|
||||
void ProcessScene(bool toscreen = false);
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/stereo3d/scoped_color_mask.h"
|
||||
|
||||
FDrawInfo * gl_drawinfo;
|
||||
|
||||
|
@ -1009,31 +1010,33 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws)
|
|||
int recursion = GLPortal::GetRecursion();
|
||||
|
||||
// Create stencil
|
||||
glStencilFunc(GL_EQUAL,recursion,~0); // create stencil
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); // increment stencil of valid pixels
|
||||
glColorMask(0,0,0,0); // don't write to the graphics buffer
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.ResetColor();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
glStencilFunc(GL_EQUAL, recursion, ~0); // create stencil
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // increment stencil of valid pixels
|
||||
{
|
||||
// Use revertible color mask, to avoid stomping on anaglyph 3D state
|
||||
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // don't write to the graphics buffer
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.ResetColor();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
|
||||
gl_RenderState.Apply();
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
gl_RenderState.Apply();
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
|
||||
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil
|
||||
glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
|
||||
|
||||
glColorMask(1,1,1,1); // don't write to the graphics buffer
|
||||
} // glColorMask(1, 1, 1, 1); // don't write to the graphics buffer
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
|
@ -1045,26 +1048,28 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws)
|
|||
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
glColorMask(0,0,0,0); // don't write to the graphics buffer
|
||||
gl_RenderState.ResetColor();
|
||||
{
|
||||
// Use revertible color mask, to avoid stomping on anaglyph 3D state
|
||||
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0,0,0,0); // don't write to the graphics buffer
|
||||
gl_RenderState.ResetColor();
|
||||
|
||||
gl_RenderState.Apply();
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
gl_RenderState.Apply();
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
// restore old stencil op.
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL,recursion,~0);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glColorMask(1,1,1,1);
|
||||
// restore old stencil op.
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, recursion, ~0);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
} // glColorMask(1, 1, 1, 1);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/stereo3d/scoped_color_mask.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
|
@ -197,7 +198,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
// Create stencil
|
||||
glStencilFunc(GL_EQUAL,recursion,~0); // create stencil
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); // increment stencil of valid pixels
|
||||
glColorMask(0,0,0,0); // don't write to the graphics buffer
|
||||
// glColorMask(0,0,0,0); // don't write to the graphics buffer
|
||||
gl_RenderState.SetEffect(EFF_STENCIL);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.ResetColor();
|
||||
|
@ -206,34 +207,36 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
|
||||
if (NeedDepthBuffer())
|
||||
{
|
||||
glDepthMask(false); // don't write to Z-buffer!
|
||||
if (!NeedDepthBuffer()) doquery = false; // too much overhead and nothing to gain.
|
||||
else if (gl_noquery) doquery = false;
|
||||
|
||||
// If occlusion query is supported let's use it to avoid rendering portals that aren't visible
|
||||
if (!QueryObject) glGenQueries(1, &QueryObject);
|
||||
if (QueryObject)
|
||||
{
|
||||
glBeginQuery(GL_SAMPLES_PASSED, QueryObject);
|
||||
}
|
||||
else doquery = false; // some kind of error happened
|
||||
ScopedColorMask colorMask(0, 0, 0, 0);
|
||||
glDepthMask(false); // don't write to Z-buffer!
|
||||
if (!NeedDepthBuffer()) doquery = false; // too much overhead and nothing to gain.
|
||||
else if (gl_noquery) doquery = false;
|
||||
|
||||
DrawPortalStencil();
|
||||
// If occlusion query is supported let's use it to avoid rendering portals that aren't visible
|
||||
if (!QueryObject) glGenQueries(1, &QueryObject);
|
||||
if (QueryObject)
|
||||
{
|
||||
glBeginQuery(GL_SAMPLES_PASSED, QueryObject);
|
||||
}
|
||||
else doquery = false; // some kind of error happened
|
||||
|
||||
glEndQuery(GL_SAMPLES_PASSED);
|
||||
DrawPortalStencil();
|
||||
|
||||
// Clear Z-buffer
|
||||
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil
|
||||
glDepthMask(true); // enable z-buffer again
|
||||
glDepthRange(1,1);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
DrawPortalStencil();
|
||||
glEndQuery(GL_SAMPLES_PASSED);
|
||||
|
||||
// set normal drawing mode
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glDepthFunc(GL_LESS);
|
||||
glColorMask(1,1,1,1);
|
||||
// Clear Z-buffer
|
||||
glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
|
||||
glDepthMask(true); // enable z-buffer again
|
||||
glDepthRange(1, 1);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
DrawPortalStencil();
|
||||
|
||||
// set normal drawing mode
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glDepthFunc(GL_LESS);
|
||||
} // glColorMask(1, 1, 1, 1);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
glDepthRange(0, 1);
|
||||
|
||||
|
@ -258,12 +261,13 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
// than the benefit.
|
||||
// Note: We must draw the stencil with z-write enabled here because there is no second pass!
|
||||
|
||||
ScopedColorMask colorMask(0, 0, 0, 0);
|
||||
glDepthMask(true);
|
||||
DrawPortalStencil();
|
||||
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glColorMask(1,1,1,1);
|
||||
// glColorMask(1,1,1,1);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false); // don't write to Z-buffer!
|
||||
|
@ -369,38 +373,39 @@ void GLPortal::End(bool usestencil)
|
|||
viewangle=savedviewangle;
|
||||
GLRenderer->mViewActor=savedviewactor;
|
||||
in_area=savedviewarea;
|
||||
GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
||||
|
||||
glColorMask(0,0,0,0); // no graphics
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
if (needdepth)
|
||||
{
|
||||
// first step: reset the depth buffer to max. depth
|
||||
glDepthRange(1,1); // always
|
||||
glDepthFunc(GL_ALWAYS); // write the farthest depth value
|
||||
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // no graphics
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
if (needdepth)
|
||||
{
|
||||
// first step: reset the depth buffer to max. depth
|
||||
glDepthRange(1, 1); // always
|
||||
glDepthFunc(GL_ALWAYS); // write the farthest depth value
|
||||
DrawPortalStencil();
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
// second step: restore the depth buffer to the previous values and reset the stencil
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthRange(0, 1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
|
||||
glStencilFunc(GL_EQUAL, recursion, ~0); // draw sky into stencil
|
||||
DrawPortalStencil();
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
// second step: restore the depth buffer to the previous values and reset the stencil
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthRange(0,1);
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
|
||||
glStencilFunc(GL_EQUAL,recursion,~0); // draw sky into stencil
|
||||
DrawPortalStencil();
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
} // glColorMask(1, 1, 1, 1);
|
||||
recursion--;
|
||||
|
||||
// restore old stencil op.
|
||||
|
@ -433,14 +438,15 @@ void GLPortal::End(bool usestencil)
|
|||
|
||||
gl_RenderState.ResetColor();
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthRange(0,1);
|
||||
glColorMask(0,0,0,0); // no graphics
|
||||
gl_RenderState.SetEffect(EFF_STENCIL);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
DrawPortalStencil();
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glColorMask(1,1,1,1);
|
||||
glDepthRange(0, 1);
|
||||
{
|
||||
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0,0,0,0); // no graphics
|
||||
gl_RenderState.SetEffect(EFF_STENCIL);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
DrawPortalStencil();
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
} // glColorMask(1, 1, 1, 1);
|
||||
glDepthFunc(GL_LESS);
|
||||
}
|
||||
PortalAll.Unclock();
|
||||
|
|
|
@ -71,6 +71,8 @@
|
|||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
#include "gl/stereo3d/scoped_view_shifter.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/utility/gl_convert.h"
|
||||
|
@ -254,6 +256,13 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio)
|
|||
gl_RenderState.Set2DMode(false);
|
||||
}
|
||||
|
||||
// raw matrix input from stereo 3d modes
|
||||
void FGLRenderer::SetProjection(FLOATTYPE matrix[4][4])
|
||||
{
|
||||
gl_RenderState.mProjectionMatrix.loadMatrix(&matrix[0][0]);
|
||||
gl_RenderState.Set2DMode(false);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Setup the modelview matrix
|
||||
|
@ -802,18 +811,36 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
|||
|
||||
retval = viewsector;
|
||||
|
||||
SetViewport(bounds);
|
||||
mCurrentFoV = fov;
|
||||
SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper
|
||||
SetViewAngle(viewangle);
|
||||
SetViewMatrix(viewx, viewy, viewz, false, false);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
// Render (potentially) multiple views for stereo 3d
|
||||
FLOATTYPE projectionMatrix[4][4];
|
||||
float viewShift[3];
|
||||
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
|
||||
stereo3dMode.SetUp();
|
||||
s3d::Stereo3DMode::const_iterator eye;
|
||||
for (eye = stereo3dMode.begin(); eye != stereo3dMode.end(); ++eye)
|
||||
{
|
||||
(*eye)->SetUp();
|
||||
// TODO: stereo specific viewport - needed when implementing side-by-side modes etc.
|
||||
SetViewport(bounds);
|
||||
mCurrentFoV = fov;
|
||||
// Stereo mode specific perspective projection
|
||||
(*eye)->GetProjection(fov, ratio, fovratio, projectionMatrix);
|
||||
SetProjection(projectionMatrix);
|
||||
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
|
||||
(*eye)->GetViewShift(GLRenderer->mAngles.Yaw, viewShift);
|
||||
s3d::ScopedViewShifter viewShifter(viewShift);
|
||||
SetViewMatrix(viewx, viewy, viewz, false, false);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
|
||||
clipper.Clear();
|
||||
angle_t a1 = FrustumAngle();
|
||||
clipper.SafeAddClipRangeRealAngles(viewangle+a1, viewangle-a1);
|
||||
clipper.Clear();
|
||||
angle_t a1 = FrustumAngle();
|
||||
clipper.SafeAddClipRangeRealAngles(viewangle + a1, viewangle - a1);
|
||||
|
||||
ProcessScene(toscreen);
|
||||
ProcessScene(toscreen);
|
||||
}
|
||||
stereo3dMode.TearDown();
|
||||
|
||||
gl_frameCount++; // This counter must be increased right before the interpolations are restored.
|
||||
interpolator.RestoreInterpolations ();
|
||||
|
|
|
@ -11,7 +11,7 @@ MaskAnaglyph::MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters)
|
|||
|
||||
|
||||
/* static */
|
||||
const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
||||
const GreenMagenta& GreenMagenta::getInstance(FLOATTYPE ipd)
|
||||
{
|
||||
static GreenMagenta instance(ipd);
|
||||
return instance;
|
||||
|
@ -19,7 +19,7 @@ const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
|||
|
||||
|
||||
/* static */
|
||||
const RedCyan& RedCyan::getInstance(float ipd)
|
||||
const RedCyan& RedCyan::getInstance(FLOATTYPE ipd)
|
||||
{
|
||||
static RedCyan instance(ipd);
|
||||
return instance;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "gl_stereo3d.h"
|
||||
#include "gl_stereo_leftright.h"
|
||||
#include "gl/system/gl_system.h"
|
||||
|
||||
|
||||
namespace s3d {
|
||||
|
|
|
@ -6,24 +6,23 @@ namespace s3d {
|
|||
|
||||
|
||||
/* virtual */
|
||||
void EyePose::GetProjection(float fov, float aspectRatio, float fovRatio, GLdouble m[4][4]) const
|
||||
void EyePose::GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio, FLOATTYPE 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 fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||
const FLOATTYPE zNear = 5.0;
|
||||
const FLOATTYPE zFar = 65536.0;
|
||||
|
||||
double sine, cotangent, deltaZ;
|
||||
double radians = fovy / 2 * M_PI / 180;
|
||||
|
||||
deltaZ = zFar - zNear;
|
||||
sine = sin(radians);
|
||||
FLOATTYPE deltaZ = zFar - zNear;
|
||||
double sine = sin(radians);
|
||||
if ((deltaZ == 0) || (sine == 0) || (aspectRatio == 0)) {
|
||||
return;
|
||||
}
|
||||
cotangent = cos(radians) / sine;
|
||||
FLOATTYPE cotangent = FLOATTYPE(cos(radians) / sine);
|
||||
|
||||
memset(m, 0, 16*sizeof(GLdouble));
|
||||
memset(m, 0, 16*sizeof(FLOATTYPE));
|
||||
m[0][0] = cotangent / aspectRatio;
|
||||
m[1][1] = cotangent;
|
||||
m[2][2] = -(zFar + zNear) / deltaZ;
|
||||
|
@ -40,7 +39,7 @@ Viewport EyePose::GetViewport(const Viewport& fullViewport) const
|
|||
|
||||
|
||||
/* virtual */
|
||||
void EyePose::GetViewShift(float yaw, float outViewShift[3]) const
|
||||
void EyePose::GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const
|
||||
{
|
||||
// pass-through for Mono view
|
||||
outViewShift[0] = 0;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define GL_STEREO3D_H_
|
||||
|
||||
#include <vector>
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/data/gl_matrix.h"
|
||||
|
||||
|
||||
/* stereoscopic 3D API */
|
||||
|
@ -24,9 +24,9 @@ class EyePose
|
|||
public:
|
||||
EyePose() {}
|
||||
virtual ~EyePose() {}
|
||||
virtual void GetProjection(float fov, float aspectRatio, float fovRatio, GLdouble outMatrix[4][4]) const;
|
||||
virtual void GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio, FLOATTYPE outMatrix[4][4]) const;
|
||||
virtual Viewport GetViewport(const Viewport& fullViewport) const;
|
||||
virtual void GetViewShift(float yaw, float outViewShift[3]) const;
|
||||
virtual void GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const;
|
||||
virtual void SetUp() const {};
|
||||
virtual void TearDown() const {};
|
||||
};
|
||||
|
|
|
@ -33,10 +33,11 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
|||
case 2:
|
||||
setCurrentMode(RedCyan::getInstance(vr_ipd));
|
||||
break;
|
||||
case 3:
|
||||
// TODO: missing indices 3, 4 for not-yet-implemented side-by-side modes, to match values from GZ3Doom
|
||||
case 5:
|
||||
setCurrentMode(LeftEyeView::getInstance(vr_ipd));
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
setCurrentMode(RightEyeView::getInstance(vr_ipd));
|
||||
break;
|
||||
case 0:
|
||||
|
|
|
@ -11,10 +11,10 @@ namespace s3d {
|
|||
|
||||
|
||||
/* virtual */
|
||||
void ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRatio, GLdouble m[4][4]) const
|
||||
void ShiftedEyePose::GetProjection(FLOATTYPE fov, FLOATTYPE aspectRatio, FLOATTYPE fovRatio, FLOATTYPE m[4][4]) const
|
||||
{
|
||||
// Lifted from gl_scene.cpp FGLRenderer::SetProjection()
|
||||
float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||
FLOATTYPE fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||
double zNear = 5.0;
|
||||
double zFar = 65536.0;
|
||||
|
||||
|
@ -33,7 +33,7 @@ void ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRatio,
|
|||
double top = fH;
|
||||
double deltaZ = zFar - zNear;
|
||||
|
||||
memset(m, 0, 16 * sizeof(GLdouble)); // set all elements to zero, cleverly
|
||||
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);
|
||||
|
@ -48,10 +48,10 @@ void ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRatio,
|
|||
|
||||
|
||||
/* virtual */
|
||||
void ShiftedEyePose::GetViewShift(float yaw, float outViewShift[3]) const
|
||||
void ShiftedEyePose::GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const
|
||||
{
|
||||
float dx = cos(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
||||
float dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
||||
FLOATTYPE dx = cos(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
||||
FLOATTYPE dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
||||
outViewShift[0] = dx;
|
||||
outViewShift[1] = dy;
|
||||
outViewShift[2] = 0;
|
||||
|
@ -59,7 +59,7 @@ void ShiftedEyePose::GetViewShift(float yaw, float outViewShift[3]) const
|
|||
|
||||
|
||||
/* static */
|
||||
const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
||||
const LeftEyeView& LeftEyeView::getInstance(FLOATTYPE ipd)
|
||||
{
|
||||
static LeftEyeView instance(ipd);
|
||||
instance.setIpd(ipd);
|
||||
|
@ -68,7 +68,7 @@ const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
|||
|
||||
|
||||
/* static */
|
||||
const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||
const RightEyeView& RightEyeView::getInstance(FLOATTYPE ipd)
|
||||
{
|
||||
static RightEyeView instance(ipd);
|
||||
instance.setIpd(ipd);
|
||||
|
|
|
@ -9,31 +9,31 @@ 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;
|
||||
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 void GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const;
|
||||
protected:
|
||||
float shift;
|
||||
FLOATTYPE 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); }
|
||||
LeftEyePose(FLOATTYPE ipd) : ShiftedEyePose( FLOATTYPE(-0.5) * ipd) {}
|
||||
FLOATTYPE getIpd() const { return FLOATTYPE(-2.0)*getShift(); }
|
||||
void setIpd(FLOATTYPE ipd) { setShift(FLOATTYPE(-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); }
|
||||
RightEyePose(FLOATTYPE ipd) : ShiftedEyePose(FLOATTYPE(+0.5)*ipd) {}
|
||||
FLOATTYPE getIpd() const { return FLOATTYPE(+2.0)*shift; }
|
||||
void setIpd(FLOATTYPE ipd) { setShift(FLOATTYPE(+0.5)*ipd); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -43,11 +43,11 @@ public:
|
|||
class LeftEyeView : public Stereo3DMode
|
||||
{
|
||||
public:
|
||||
static const LeftEyeView& getInstance(float ipd);
|
||||
static const LeftEyeView& getInstance(FLOATTYPE ipd);
|
||||
|
||||
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
||||
float getIpd() const { return eye.getIpd(); }
|
||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||
LeftEyeView(FLOATTYPE ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
||||
FLOATTYPE getIpd() const { return eye.getIpd(); }
|
||||
void setIpd(FLOATTYPE ipd) { eye.setIpd(ipd); }
|
||||
protected:
|
||||
LeftEyePose eye;
|
||||
};
|
||||
|
@ -56,11 +56,11 @@ protected:
|
|||
class RightEyeView : public Stereo3DMode
|
||||
{
|
||||
public:
|
||||
static const RightEyeView& getInstance(float ipd);
|
||||
static const RightEyeView& getInstance(FLOATTYPE ipd);
|
||||
|
||||
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
||||
float getIpd() const { return eye.getIpd(); }
|
||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||
RightEyeView(FLOATTYPE ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
||||
FLOATTYPE getIpd() const { return eye.getIpd(); }
|
||||
void setIpd(FLOATTYPE ipd) { eye.setIpd(ipd); }
|
||||
protected:
|
||||
RightEyePose eye;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef GL_STEREO3D_SCOPED_COLOR_MASK_H_
|
||||
#define GL_STEREO3D_SCOPED_COLOR_MASK_H_
|
||||
|
||||
#include "gl/glew.h"
|
||||
#include "gl/system/gl_system.h"
|
||||
|
||||
/**
|
||||
* Temporarily change color mask
|
||||
|
@ -10,28 +10,15 @@ 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;
|
||||
}
|
||||
glGetBooleanv(GL_COLOR_WRITEMASK, saved);
|
||||
glColorMask(r, g, b, a);
|
||||
}
|
||||
void revert() {
|
||||
if (isPushed) {
|
||||
glPopAttrib();
|
||||
isPushed = false;
|
||||
}
|
||||
~ScopedColorMask() {
|
||||
glColorMask(saved[0], saved[1], saved[2], saved[3]);
|
||||
}
|
||||
private:
|
||||
bool isPushed;
|
||||
GLboolean saved[4];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -124,6 +124,15 @@ OptionValue "FuzzStyle"
|
|||
//5, "Jagged fuzz" I can't see any difference between this and 4 so it's disabled for now.
|
||||
}
|
||||
|
||||
OptionValue VRMode
|
||||
{
|
||||
0, "Normal"
|
||||
1, "Green/Magenta"
|
||||
2, "Red/Cyan"
|
||||
5, "Left Eye"
|
||||
6, "Right Eye"
|
||||
}
|
||||
|
||||
OptionMenu "GLTextureGLOptions"
|
||||
{
|
||||
Title "TEXTURE OPTIONS"
|
||||
|
@ -173,5 +182,6 @@ OptionMenu "GLPrefOptions"
|
|||
Option "Particle style", gl_particles_style, "Particles"
|
||||
Slider "Ambient light level", gl_light_ambient, 1.0, 255.0, 5.0
|
||||
Option "Rendering quality", gl_render_precise, "Precision"
|
||||
Option "Stereo 3D VR", vr_mode, "VRMode"
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue