mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-24 21:11:52 +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/
|
/zlib/x64/
|
||||||
/build_vc2013_64bit
|
/build_vc2013_64bit
|
||||||
/build_vc2015
|
/build_vc2015
|
||||||
|
/build_cmake
|
||||||
|
|
|
@ -762,6 +762,7 @@ file( GLOB HEADER_FILES
|
||||||
gl/models/*.h
|
gl/models/*.h
|
||||||
gl/renderer/*.h
|
gl/renderer/*.h
|
||||||
gl/scene/*.h
|
gl/scene/*.h
|
||||||
|
gl/stereo3d/*.h
|
||||||
gl/shaders/*.h
|
gl/shaders/*.h
|
||||||
gl/system/*.h
|
gl/system/*.h
|
||||||
gl/textures/*.h
|
gl/textures/*.h
|
||||||
|
@ -1120,6 +1121,11 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||||
gl/scene/gl_walls_draw.cpp
|
gl/scene/gl_walls_draw.cpp
|
||||||
gl/scene/gl_vertex.cpp
|
gl/scene/gl_vertex.cpp
|
||||||
gl/scene/gl_spritelight.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_dynlight.cpp
|
||||||
gl/dynlights/gl_glow.cpp
|
gl/dynlights/gl_glow.cpp
|
||||||
gl/dynlights/gl_dynlight1.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\\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\\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\\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\\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\\System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/system/.+")
|
||||||
source_group("OpenGL Renderer\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/textures/.+")
|
source_group("OpenGL Renderer\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/textures/.+")
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
|
#include "gl/data/gl_matrix.h"
|
||||||
|
|
||||||
struct particle_t;
|
struct particle_t;
|
||||||
class FCanvasTexture;
|
class FCanvasTexture;
|
||||||
|
@ -120,6 +121,7 @@ public:
|
||||||
void Flush() {}
|
void Flush() {}
|
||||||
|
|
||||||
void SetProjection(float fov, float ratio, float fovratio);
|
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 SetViewMatrix(fixed_t viewx, fixed_t viewy, fixed_t viewz, bool mirror, bool planemirror);
|
||||||
void ProcessScene(bool toscreen = false);
|
void ProcessScene(bool toscreen = false);
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include "gl/utility/gl_clock.h"
|
#include "gl/utility/gl_clock.h"
|
||||||
#include "gl/utility/gl_templates.h"
|
#include "gl/utility/gl_templates.h"
|
||||||
#include "gl/shaders/gl_shader.h"
|
#include "gl/shaders/gl_shader.h"
|
||||||
|
#include "gl/stereo3d/scoped_color_mask.h"
|
||||||
|
|
||||||
FDrawInfo * gl_drawinfo;
|
FDrawInfo * gl_drawinfo;
|
||||||
|
|
||||||
|
@ -1009,31 +1010,33 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws)
|
||||||
int recursion = GLPortal::GetRecursion();
|
int recursion = GLPortal::GetRecursion();
|
||||||
|
|
||||||
// Create stencil
|
// Create stencil
|
||||||
glStencilFunc(GL_EQUAL,recursion,~0); // create stencil
|
glStencilFunc(GL_EQUAL, recursion, ~0); // create stencil
|
||||||
glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); // increment stencil of valid pixels
|
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);
|
// Use revertible color mask, to avoid stomping on anaglyph 3D state
|
||||||
gl_RenderState.ResetColor();
|
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // don't write to the graphics buffer
|
||||||
glEnable(GL_DEPTH_TEST);
|
gl_RenderState.EnableTexture(false);
|
||||||
glDepthMask(true);
|
gl_RenderState.ResetColor();
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthMask(true);
|
||||||
|
|
||||||
gl_RenderState.Apply();
|
gl_RenderState.Apply();
|
||||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||||
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
||||||
ptr++;
|
ptr++;
|
||||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||||
|
|
||||||
|
|
||||||
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into 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
|
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);
|
gl_RenderState.EnableTexture(true);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
|
@ -1045,26 +1048,28 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws)
|
||||||
|
|
||||||
glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
|
glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
|
||||||
gl_RenderState.EnableTexture(false);
|
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();
|
gl_RenderState.Apply();
|
||||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||||
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
||||||
ptr++;
|
ptr++;
|
||||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||||
|
|
||||||
// restore old stencil op.
|
// restore old stencil op.
|
||||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
glStencilFunc(GL_EQUAL,recursion,~0);
|
glStencilFunc(GL_EQUAL, recursion, ~0);
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.EnableTexture(true);
|
||||||
glColorMask(1,1,1,1);
|
} // glColorMask(1, 1, 1, 1);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "gl/scene/gl_drawinfo.h"
|
#include "gl/scene/gl_drawinfo.h"
|
||||||
#include "gl/scene/gl_portal.h"
|
#include "gl/scene/gl_portal.h"
|
||||||
#include "gl/shaders/gl_shader.h"
|
#include "gl/shaders/gl_shader.h"
|
||||||
|
#include "gl/stereo3d/scoped_color_mask.h"
|
||||||
#include "gl/textures/gl_material.h"
|
#include "gl/textures/gl_material.h"
|
||||||
#include "gl/utility/gl_clock.h"
|
#include "gl/utility/gl_clock.h"
|
||||||
#include "gl/utility/gl_templates.h"
|
#include "gl/utility/gl_templates.h"
|
||||||
|
@ -197,7 +198,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
||||||
// Create stencil
|
// Create stencil
|
||||||
glStencilFunc(GL_EQUAL,recursion,~0); // create stencil
|
glStencilFunc(GL_EQUAL,recursion,~0); // create stencil
|
||||||
glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); // increment stencil of valid pixels
|
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.SetEffect(EFF_STENCIL);
|
||||||
gl_RenderState.EnableTexture(false);
|
gl_RenderState.EnableTexture(false);
|
||||||
gl_RenderState.ResetColor();
|
gl_RenderState.ResetColor();
|
||||||
|
@ -206,34 +207,36 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
||||||
|
|
||||||
if (NeedDepthBuffer())
|
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);
|
ScopedColorMask colorMask(0, 0, 0, 0);
|
||||||
}
|
glDepthMask(false); // don't write to Z-buffer!
|
||||||
else doquery = false; // some kind of error happened
|
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
|
glEndQuery(GL_SAMPLES_PASSED);
|
||||||
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
|
// Clear Z-buffer
|
||||||
gl_RenderState.EnableTexture(true);
|
glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil
|
||||||
glDepthFunc(GL_LESS);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
|
||||||
glColorMask(1,1,1,1);
|
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);
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
glDepthRange(0, 1);
|
glDepthRange(0, 1);
|
||||||
|
|
||||||
|
@ -258,12 +261,13 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
||||||
// than the benefit.
|
// than the benefit.
|
||||||
// Note: We must draw the stencil with z-write enabled here because there is no second pass!
|
// 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);
|
glDepthMask(true);
|
||||||
DrawPortalStencil();
|
DrawPortalStencil();
|
||||||
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into 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
|
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.EnableTexture(true);
|
||||||
glColorMask(1,1,1,1);
|
// glColorMask(1,1,1,1);
|
||||||
gl_RenderState.SetEffect(EFF_NONE);
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(false); // don't write to Z-buffer!
|
glDepthMask(false); // don't write to Z-buffer!
|
||||||
|
@ -369,38 +373,39 @@ void GLPortal::End(bool usestencil)
|
||||||
viewangle=savedviewangle;
|
viewangle=savedviewangle;
|
||||||
GLRenderer->mViewActor=savedviewactor;
|
GLRenderer->mViewActor=savedviewactor;
|
||||||
in_area=savedviewarea;
|
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
|
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // no graphics
|
||||||
glDepthRange(1,1); // always
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
glDepthFunc(GL_ALWAYS); // write the farthest depth value
|
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();
|
DrawPortalStencil();
|
||||||
}
|
glDepthFunc(GL_LESS);
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.EnableTexture(true);
|
||||||
gl_RenderState.SetEffect(EFF_NONE);
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
glColorMask(1, 1, 1, 1);
|
} // glColorMask(1, 1, 1, 1);
|
||||||
recursion--;
|
recursion--;
|
||||||
|
|
||||||
// restore old stencil op.
|
// restore old stencil op.
|
||||||
|
@ -433,14 +438,15 @@ void GLPortal::End(bool usestencil)
|
||||||
|
|
||||||
gl_RenderState.ResetColor();
|
gl_RenderState.ResetColor();
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glDepthRange(0,1);
|
glDepthRange(0, 1);
|
||||||
glColorMask(0,0,0,0); // no graphics
|
{
|
||||||
gl_RenderState.SetEffect(EFF_STENCIL);
|
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0,0,0,0); // no graphics
|
||||||
gl_RenderState.EnableTexture(false);
|
gl_RenderState.SetEffect(EFF_STENCIL);
|
||||||
DrawPortalStencil();
|
gl_RenderState.EnableTexture(false);
|
||||||
gl_RenderState.SetEffect(EFF_NONE);
|
DrawPortalStencil();
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
glColorMask(1,1,1,1);
|
gl_RenderState.EnableTexture(true);
|
||||||
|
} // glColorMask(1, 1, 1, 1);
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
}
|
}
|
||||||
PortalAll.Unclock();
|
PortalAll.Unclock();
|
||||||
|
|
|
@ -71,6 +71,8 @@
|
||||||
#include "gl/scene/gl_drawinfo.h"
|
#include "gl/scene/gl_drawinfo.h"
|
||||||
#include "gl/scene/gl_portal.h"
|
#include "gl/scene/gl_portal.h"
|
||||||
#include "gl/shaders/gl_shader.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/textures/gl_material.h"
|
||||||
#include "gl/utility/gl_clock.h"
|
#include "gl/utility/gl_clock.h"
|
||||||
#include "gl/utility/gl_convert.h"
|
#include "gl/utility/gl_convert.h"
|
||||||
|
@ -254,6 +256,13 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio)
|
||||||
gl_RenderState.Set2DMode(false);
|
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
|
// Setup the modelview matrix
|
||||||
|
@ -802,18 +811,36 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
||||||
|
|
||||||
retval = viewsector;
|
retval = viewsector;
|
||||||
|
|
||||||
SetViewport(bounds);
|
// Render (potentially) multiple views for stereo 3d
|
||||||
mCurrentFoV = fov;
|
FLOATTYPE projectionMatrix[4][4];
|
||||||
SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper
|
float viewShift[3];
|
||||||
SetViewAngle(viewangle);
|
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
|
||||||
SetViewMatrix(viewx, viewy, viewz, false, false);
|
stereo3dMode.SetUp();
|
||||||
gl_RenderState.ApplyMatrices();
|
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();
|
clipper.Clear();
|
||||||
angle_t a1 = FrustumAngle();
|
angle_t a1 = FrustumAngle();
|
||||||
clipper.SafeAddClipRangeRealAngles(viewangle+a1, viewangle-a1);
|
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.
|
gl_frameCount++; // This counter must be increased right before the interpolations are restored.
|
||||||
interpolator.RestoreInterpolations ();
|
interpolator.RestoreInterpolations ();
|
||||||
|
|
|
@ -11,7 +11,7 @@ MaskAnaglyph::MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters)
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
const GreenMagenta& GreenMagenta::getInstance(FLOATTYPE ipd)
|
||||||
{
|
{
|
||||||
static GreenMagenta instance(ipd);
|
static GreenMagenta instance(ipd);
|
||||||
return instance;
|
return instance;
|
||||||
|
@ -19,7 +19,7 @@ const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const RedCyan& RedCyan::getInstance(float ipd)
|
const RedCyan& RedCyan::getInstance(FLOATTYPE ipd)
|
||||||
{
|
{
|
||||||
static RedCyan instance(ipd);
|
static RedCyan instance(ipd);
|
||||||
return instance;
|
return instance;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "gl_stereo3d.h"
|
#include "gl_stereo3d.h"
|
||||||
#include "gl_stereo_leftright.h"
|
#include "gl_stereo_leftright.h"
|
||||||
|
#include "gl/system/gl_system.h"
|
||||||
|
|
||||||
|
|
||||||
namespace s3d {
|
namespace s3d {
|
||||||
|
|
|
@ -6,24 +6,23 @@ namespace s3d {
|
||||||
|
|
||||||
|
|
||||||
/* virtual */
|
/* 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()
|
// Lifted from gl_scene.cpp FGLRenderer::SetProjection()
|
||||||
float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
double fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio));
|
||||||
const double zNear = 5.0;
|
const FLOATTYPE zNear = 5.0;
|
||||||
const double zFar = 65536.0;
|
const FLOATTYPE zFar = 65536.0;
|
||||||
|
|
||||||
double sine, cotangent, deltaZ;
|
|
||||||
double radians = fovy / 2 * M_PI / 180;
|
double radians = fovy / 2 * M_PI / 180;
|
||||||
|
|
||||||
deltaZ = zFar - zNear;
|
FLOATTYPE deltaZ = zFar - zNear;
|
||||||
sine = sin(radians);
|
double sine = sin(radians);
|
||||||
if ((deltaZ == 0) || (sine == 0) || (aspectRatio == 0)) {
|
if ((deltaZ == 0) || (sine == 0) || (aspectRatio == 0)) {
|
||||||
return;
|
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[0][0] = cotangent / aspectRatio;
|
||||||
m[1][1] = cotangent;
|
m[1][1] = cotangent;
|
||||||
m[2][2] = -(zFar + zNear) / deltaZ;
|
m[2][2] = -(zFar + zNear) / deltaZ;
|
||||||
|
@ -40,7 +39,7 @@ Viewport EyePose::GetViewport(const Viewport& fullViewport) const
|
||||||
|
|
||||||
|
|
||||||
/* virtual */
|
/* virtual */
|
||||||
void EyePose::GetViewShift(float yaw, float outViewShift[3]) const
|
void EyePose::GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const
|
||||||
{
|
{
|
||||||
// pass-through for Mono view
|
// pass-through for Mono view
|
||||||
outViewShift[0] = 0;
|
outViewShift[0] = 0;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define GL_STEREO3D_H_
|
#define GL_STEREO3D_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "gl/system/gl_system.h"
|
#include "gl/data/gl_matrix.h"
|
||||||
|
|
||||||
|
|
||||||
/* stereoscopic 3D API */
|
/* stereoscopic 3D API */
|
||||||
|
@ -24,9 +24,9 @@ class EyePose
|
||||||
public:
|
public:
|
||||||
EyePose() {}
|
EyePose() {}
|
||||||
virtual ~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 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 SetUp() const {};
|
||||||
virtual void TearDown() const {};
|
virtual void TearDown() const {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,10 +33,11 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
||||||
case 2:
|
case 2:
|
||||||
setCurrentMode(RedCyan::getInstance(vr_ipd));
|
setCurrentMode(RedCyan::getInstance(vr_ipd));
|
||||||
break;
|
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));
|
setCurrentMode(LeftEyeView::getInstance(vr_ipd));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 6:
|
||||||
setCurrentMode(RightEyeView::getInstance(vr_ipd));
|
setCurrentMode(RightEyeView::getInstance(vr_ipd));
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -11,10 +11,10 @@ namespace s3d {
|
||||||
|
|
||||||
|
|
||||||
/* virtual */
|
/* 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()
|
// 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 zNear = 5.0;
|
||||||
double zFar = 65536.0;
|
double zFar = 65536.0;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ void ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRatio,
|
||||||
double top = fH;
|
double top = fH;
|
||||||
double deltaZ = zFar - zNear;
|
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
|
// https://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml
|
||||||
m[0][0] = 2 * zNear / (right - left);
|
m[0][0] = 2 * zNear / (right - left);
|
||||||
|
@ -48,10 +48,10 @@ void ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRatio,
|
||||||
|
|
||||||
|
|
||||||
/* virtual */
|
/* 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;
|
FLOATTYPE dx = cos(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
||||||
float dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
FLOATTYPE dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
|
||||||
outViewShift[0] = dx;
|
outViewShift[0] = dx;
|
||||||
outViewShift[1] = dy;
|
outViewShift[1] = dy;
|
||||||
outViewShift[2] = 0;
|
outViewShift[2] = 0;
|
||||||
|
@ -59,7 +59,7 @@ void ShiftedEyePose::GetViewShift(float yaw, float outViewShift[3]) const
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
const LeftEyeView& LeftEyeView::getInstance(FLOATTYPE ipd)
|
||||||
{
|
{
|
||||||
static LeftEyeView instance(ipd);
|
static LeftEyeView instance(ipd);
|
||||||
instance.setIpd(ipd);
|
instance.setIpd(ipd);
|
||||||
|
@ -68,7 +68,7 @@ const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const RightEyeView& RightEyeView::getInstance(float ipd)
|
const RightEyeView& RightEyeView::getInstance(FLOATTYPE ipd)
|
||||||
{
|
{
|
||||||
static RightEyeView instance(ipd);
|
static RightEyeView instance(ipd);
|
||||||
instance.setIpd(ipd);
|
instance.setIpd(ipd);
|
||||||
|
|
|
@ -9,31 +9,31 @@ namespace s3d {
|
||||||
class ShiftedEyePose : public EyePose
|
class ShiftedEyePose : public EyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShiftedEyePose(float shift) : shift(shift) {};
|
ShiftedEyePose(FLOATTYPE shift) : shift(shift) {};
|
||||||
float getShift() const { return shift; }
|
FLOATTYPE getShift() const { return shift; }
|
||||||
void setShift(float shift) { this->shift = shift; }
|
void setShift(FLOATTYPE shift) { this->shift = shift; }
|
||||||
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 void GetViewShift(float yaw, float outViewShift[3]) const;
|
virtual void GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const;
|
||||||
protected:
|
protected:
|
||||||
float shift;
|
FLOATTYPE shift;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class LeftEyePose : public ShiftedEyePose
|
class LeftEyePose : public ShiftedEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LeftEyePose(float ipd) : ShiftedEyePose(-0.5*ipd) {}
|
LeftEyePose(FLOATTYPE ipd) : ShiftedEyePose( FLOATTYPE(-0.5) * ipd) {}
|
||||||
float getIpd() const { return -2.0*getShift(); }
|
FLOATTYPE getIpd() const { return FLOATTYPE(-2.0)*getShift(); }
|
||||||
void setIpd(float ipd) { setShift(-0.5*ipd); }
|
void setIpd(FLOATTYPE ipd) { setShift(FLOATTYPE(-0.5)*ipd); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RightEyePose : public ShiftedEyePose
|
class RightEyePose : public ShiftedEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RightEyePose(float ipd) : ShiftedEyePose(+0.5*ipd) {}
|
RightEyePose(FLOATTYPE ipd) : ShiftedEyePose(FLOATTYPE(+0.5)*ipd) {}
|
||||||
float getIpd() const { return +2.0*shift; }
|
FLOATTYPE getIpd() const { return FLOATTYPE(+2.0)*shift; }
|
||||||
void setIpd(float ipd) { setShift(+0.5*ipd); }
|
void setIpd(FLOATTYPE ipd) { setShift(FLOATTYPE(+0.5)*ipd); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,11 +43,11 @@ public:
|
||||||
class LeftEyeView : public Stereo3DMode
|
class LeftEyeView : public Stereo3DMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const LeftEyeView& getInstance(float ipd);
|
static const LeftEyeView& getInstance(FLOATTYPE ipd);
|
||||||
|
|
||||||
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
LeftEyeView(FLOATTYPE ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
||||||
float getIpd() const { return eye.getIpd(); }
|
FLOATTYPE getIpd() const { return eye.getIpd(); }
|
||||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
void setIpd(FLOATTYPE ipd) { eye.setIpd(ipd); }
|
||||||
protected:
|
protected:
|
||||||
LeftEyePose eye;
|
LeftEyePose eye;
|
||||||
};
|
};
|
||||||
|
@ -56,11 +56,11 @@ protected:
|
||||||
class RightEyeView : public Stereo3DMode
|
class RightEyeView : public Stereo3DMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const RightEyeView& getInstance(float ipd);
|
static const RightEyeView& getInstance(FLOATTYPE ipd);
|
||||||
|
|
||||||
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
RightEyeView(FLOATTYPE ipd) : eye(ipd) { eye_ptrs.push_back(&eye); }
|
||||||
float getIpd() const { return eye.getIpd(); }
|
FLOATTYPE getIpd() const { return eye.getIpd(); }
|
||||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
void setIpd(FLOATTYPE ipd) { eye.setIpd(ipd); }
|
||||||
protected:
|
protected:
|
||||||
RightEyePose eye;
|
RightEyePose eye;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef GL_STEREO3D_SCOPED_COLOR_MASK_H_
|
#ifndef GL_STEREO3D_SCOPED_COLOR_MASK_H_
|
||||||
#define 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
|
* Temporarily change color mask
|
||||||
|
@ -10,28 +10,15 @@ class ScopedColorMask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScopedColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a)
|
ScopedColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a)
|
||||||
: isPushed(false)
|
|
||||||
{
|
{
|
||||||
setColorMask(r, g, b, a);
|
glGetBooleanv(GL_COLOR_WRITEMASK, saved);
|
||||||
}
|
|
||||||
~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);
|
glColorMask(r, g, b, a);
|
||||||
}
|
}
|
||||||
void revert() {
|
~ScopedColorMask() {
|
||||||
if (isPushed) {
|
glColorMask(saved[0], saved[1], saved[2], saved[3]);
|
||||||
glPopAttrib();
|
|
||||||
isPushed = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private:
|
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.
|
//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"
|
OptionMenu "GLTextureGLOptions"
|
||||||
{
|
{
|
||||||
Title "TEXTURE OPTIONS"
|
Title "TEXTURE OPTIONS"
|
||||||
|
@ -173,5 +182,6 @@ OptionMenu "GLPrefOptions"
|
||||||
Option "Particle style", gl_particles_style, "Particles"
|
Option "Particle style", gl_particles_style, "Particles"
|
||||||
Slider "Ambient light level", gl_light_ambient, 1.0, 255.0, 5.0
|
Slider "Ambient light level", gl_light_ambient, 1.0, 255.0, 5.0
|
||||||
Option "Rendering quality", gl_render_precise, "Precision"
|
Option "Rendering quality", gl_render_precise, "Precision"
|
||||||
|
Option "Stereo 3D VR", vr_mode, "VRMode"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue