Skip to content

Instantly share code, notes, and snippets.

@classilla
Created October 5, 2020 04:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save classilla/c777e6137a921e56aa03d8202c178338 to your computer and use it in GitHub Desktop.
Save classilla/c777e6137a921e56aa03d8202c178338 to your computer and use it in GitHub Desktop.
Convert Quakespasm to use interlaced R-L video for passive 3D monitors. See https://oldvcr.blogspot.com/2020/10/stereoscopic-computing-converting-quake.html
--- gl_rmain.c.OLD 2020-08-02 16:35:29.798497930 -0700
+++ gl_rmain.c 2020-10-03 23:32:00.309704966 -0700
@@ -77,16 +77,17 @@
cvar_t gl_affinemodels = {"gl_affinemodels","0",CVAR_NONE};
cvar_t gl_polyblend = {"gl_polyblend","1",CVAR_NONE};
cvar_t gl_flashblend = {"gl_flashblend","0",CVAR_ARCHIVE};
cvar_t gl_playermip = {"gl_playermip","0",CVAR_NONE};
cvar_t gl_nocolors = {"gl_nocolors","0",CVAR_NONE};
//johnfitz -- new cvars
cvar_t r_stereo = {"r_stereo","0",CVAR_NONE};
+cvar_t r_stereomode = {"r_stereomode","3",CVAR_NONE};
cvar_t r_stereodepth = {"r_stereodepth","128",CVAR_NONE};
cvar_t r_clearcolor = {"r_clearcolor","2",CVAR_ARCHIVE};
cvar_t r_drawflat = {"r_drawflat","0",CVAR_NONE};
cvar_t r_flatlightstyles = {"r_flatlightstyles", "0", CVAR_NONE};
cvar_t gl_fullbrights = {"gl_fullbrights", "1", CVAR_ARCHIVE};
cvar_t gl_farclip = {"gl_farclip", "16384", CVAR_ARCHIVE};
cvar_t gl_overbright = {"gl_overbright", "1", CVAR_ARCHIVE};
cvar_t gl_overbright_models = {"gl_overbright_models", "1", CVAR_ARCHIVE};
@@ -109,16 +110,65 @@
cvar_t r_slimealpha = {"r_slimealpha","0",CVAR_NONE};
float map_wateralpha, map_lavaalpha, map_telealpha, map_slimealpha;
qboolean r_drawflat_cheatsafe, r_fullbright_cheatsafe, r_lightmap_cheatsafe, r_drawworld_cheatsafe; //johnfitz
cvar_t r_scale = {"r_scale", "1", CVAR_ARCHIVE};
+qboolean stenciled = false;
+
+// 3D interlace using stencil buffer
+void
+RB_InterlaceStencil()
+{
+ GLint gliY;
+ if (stenciled) return;
+
+ // r_stereomode 1: old anaglyph
+ // r_stereomode 2: left-right, r_stereo 3: right-left
+
+ // init draw coordinates for stencil buffer
+ glViewport(0,0,glwidth,glheight);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0,glwidth-1,0.0,glheight-1,-1,1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ // draw interlaced stencil
+ glEnable(GL_STENCIL_TEST);
+ glDisable(GL_DEPTH_TEST);
+ glClear(GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glClearStencil(0);
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ glDepthMask(GL_FALSE);
+ glStencilFunc(GL_NEVER, 1, 0xff);
+ glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
+ glStencilMask(0xff);
+ glClear(GL_STENCIL_BUFFER_BIT);
+
+ for (gliY=(r_stereo.value == 3 ? 1 : 0); gliY<glheight; gliY+=2)
+ {
+ glLineWidth(1);
+ glBegin(GL_LINES);
+ glVertex2f(0,gliY);
+ glVertex2f(glwidth,gliY);
+ glEnd();
+ }
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glDepthMask(GL_TRUE);
+ glStencilMask(0x00);
+ stenciled = true;
+}
+
//==============================================================================
//
// GLSL GAMMA CORRECTION
//
//==============================================================================
static GLuint r_gamma_texture;
static GLuint r_gamma_program;
@@ -518,19 +568,16 @@
R_Clear -- johnfitz -- rewritten and gutted
=============
*/
void R_Clear (void)
{
unsigned int clearbits;
clearbits = GL_DEPTH_BUFFER_BIT;
- // from mh -- if we get a stencil buffer, we should clear it, even though we don't use it
- if (gl_stencilbits)
- clearbits |= GL_STENCIL_BUFFER_BIT;
if (gl_clear.value)
clearbits |= GL_COLOR_BUFFER_BIT;
glClear (clearbits);
}
/*
===============
R_SetupScene -- johnfitz -- this is the stuff that needs to be done once per eye in stereo mode
@@ -870,42 +917,29 @@
*/
void R_DrawShadows (void)
{
int i;
if (!r_shadows.value || !r_drawentities.value || r_drawflat_cheatsafe || r_lightmap_cheatsafe)
return;
- // Use stencil buffer to prevent self-intersecting shadows, from Baker (MarkV)
- if (gl_stencilbits)
- {
- glClear(GL_STENCIL_BUFFER_BIT);
- glStencilFunc(GL_EQUAL, 0, ~0);
- glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
- glEnable(GL_STENCIL_TEST);
- }
-
for (i=0 ; i<cl_numvisedicts ; i++)
{
currententity = cl_visedicts[i];
if (currententity->model->type != mod_alias)
continue;
if (currententity == &cl.viewent)
return;
GL_DrawAliasShadow (currententity);
}
- if (gl_stencilbits)
- {
- glDisable(GL_STENCIL_TEST);
- }
}
/*
================
R_RenderScene
================
*/
void R_RenderScene (void)
@@ -1082,36 +1116,65 @@
if (r_stereo.value)
{
float eyesep = CLAMP(-8.0f, r_stereo.value, 8.0f);
float fdepth = CLAMP(32.0f, r_stereodepth.value, 1024.0f);
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
//render left eye (red)
- glColorMask(1, 0, 0, 1);
+ if (r_stereomode.value == 1)
+ {
+ glColorMask(1, 0, 0, 1);
+ }
+ else
+ {
+ // 0 = first line (2), 1 = second (3)
+ RB_InterlaceStencil();
+ glStencilFunc(GL_EQUAL,
+ (r_stereomode.value == 2) ? 0 : 1,
+ 0xff);
+ }
VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg);
frustum_skew = 0.5 * eyesep * NEARCLIP / fdepth;
srand((int) (cl.time * 1000)); //sync random stuff between eyes
R_RenderScene ();
//render right eye (cyan)
glClear (GL_DEPTH_BUFFER_BIT);
- glColorMask(0, 1, 1, 1);
+
+ if (r_stereomode.value == 1)
+ {
+ glColorMask(0, 1, 1, 1);
+ }
+ else
+ {
+ glStencilFunc(GL_EQUAL,
+ (r_stereomode.value == 2) ? 1 : 0,
+ 0xff);
+ }
VectorMA (r_refdef.vieworg, 1.0f * eyesep, vright, r_refdef.vieworg);
frustum_skew = -frustum_skew;
srand((int) (cl.time * 1000)); //sync random stuff between eyes
R_RenderScene ();
//restore
- glColorMask(1, 1, 1, 1);
+ if (r_stereomode.value == 1)
+ {
+ glColorMask(1, 1, 1, 1);
+ }
+ else
+ {
+ glStencilFunc(GL_ALWAYS, 1, 0xff);
+ }
+
VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg);
frustum_skew = 0.0f;
}
else
{
R_RenderScene ();
}
//johnfitz
--- gl_rmisc.c.OLD 2020-10-04 18:40:48.710076545 -0700
+++ gl_rmisc.c 2020-10-03 23:34:15.643555455 -0700
@@ -21,16 +21,17 @@
*/
// r_misc.c
#include "quakedef.h"
//johnfitz -- new cvars
extern cvar_t r_stereo;
+extern cvar_t r_stereomode;
extern cvar_t r_stereodepth;
extern cvar_t r_clearcolor;
extern cvar_t r_drawflat;
extern cvar_t r_flatlightstyles;
extern cvar_t gl_fullbrights;
extern cvar_t gl_farclip;
extern cvar_t gl_overbright;
extern cvar_t gl_overbright_models;
@@ -200,16 +201,17 @@
Cvar_RegisterVariable (&gl_affinemodels);
Cvar_RegisterVariable (&gl_polyblend);
Cvar_RegisterVariable (&gl_flashblend);
Cvar_RegisterVariable (&gl_playermip);
Cvar_RegisterVariable (&gl_nocolors);
//johnfitz -- new cvars
Cvar_RegisterVariable (&r_stereo);
+ Cvar_RegisterVariable (&r_stereomode);
Cvar_RegisterVariable (&r_stereodepth);
Cvar_RegisterVariable (&r_clearcolor);
Cvar_SetCallback (&r_clearcolor, R_SetClearColor_f);
Cvar_RegisterVariable (&r_waterquality);
Cvar_RegisterVariable (&r_oldwater);
Cvar_RegisterVariable (&r_waterwarp);
Cvar_RegisterVariable (&r_drawflat);
Cvar_RegisterVariable (&r_flatlightstyles);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment