Index: tr_backend.c =================================================================== --- tr_backend.c (revision 2260) +++ tr_backend.c (working copy) @@ -507,9 +507,54 @@ } else { qglDisable (GL_CLIP_PLANE0); } + + backEnd.doneStereoInterlace = qfalse; } +void +RB_InterlaceStencil(int gliWindowWidth, int gliWindowHeight) +{ + GLint gliY; + if (backEnd.doneStereoInterlace == qtrue || r_stereoEnabled->integer < 2) return; + // r_stereoEnabled 2 : left-right interlaced output + // r_stereoEnabled 3 : right-left interlaced output + + backEnd.doneStereoInterlace = qtrue; + + // seting screen-corresponding geometry + qglViewport(0,0,gliWindowWidth,gliWindowHeight); + qglMatrixMode(GL_MODELVIEW); + qglLoadIdentity(); + qglMatrixMode (GL_PROJECTION); + qglLoadIdentity(); + qglOrtho(0.0,gliWindowWidth-1,0.0,gliWindowHeight-1,-1,1); + qglMatrixMode(GL_MODELVIEW); + qglLoadIdentity(); + + // clearing and configuring stencil drawing + qglDrawBuffer(GL_BACK); + qglEnable(GL_STENCIL_TEST); + qglClearStencil(0); + qglClear(GL_STENCIL_BUFFER_BIT); + qglStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE); // colorbuffer is copied to stencil + qglDisable(GL_DEPTH_TEST); + qglStencilFunc(GL_NEVER,1,1); // to avoid interaction with stencil content + + // drawing stencil pattern + qglColor4f(1,1,1,0); // alpha is 0 to not interfere with alpha tests + for (gliY=(r_stereoEnabled->integer == 3 ? 1 : 0); gliYinteger >= 2) // 2d must be drawn on both eyes + qglStencilFunc(GL_ALWAYS, 1, 1); + // set 2D virtual screen size qglViewport( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); qglScissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); @@ -961,9 +1013,17 @@ const drawBufferCommand_t *cmd; cmd = (const drawBufferCommand_t *)data; + + if (r_stereoEnabled->integer >= 2) { + qglDrawBuffer( GL_BACK ); + if (cmd->buffer == GL_BACK_LEFT) + qglStencilFunc(GL_NOTEQUAL,1,1); + else + qglStencilFunc(GL_EQUAL,1,1); + } + else + qglDrawBuffer( cmd->buffer ); - qglDrawBuffer( cmd->buffer ); - // clear screen for debugging if ( r_clear->integer ) { qglClearColor( 1, 0, 0.5, 1 ); @@ -1079,6 +1139,9 @@ const void *RB_SwapBuffers( const void *data ) { const swapBuffersCommand_t *cmd; + if (r_stereoEnabled->integer >= 2) + qglStencilFunc(GL_ALWAYS, 1, 1); + // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); @@ -1120,6 +1183,8 @@ backEnd.projection2D = qfalse; + backEnd.doneStereoInterlace = qfalse; + return (const void *)(cmd + 1); } Index: tr_cmds.c =================================================================== --- tr_cmds.c (revision 2260) +++ tr_cmds.c (working copy) @@ -441,14 +441,17 @@ { ri.Printf( PRINT_ALL, "Warning: not enough stencil bits to measure overdraw: %d\n", glConfig.stencilBits ); ri.Cvar_Set( "r_measureOverdraw", "0" ); - r_measureOverdraw->modified = qfalse; } else if ( r_shadows->integer == 2 ) { ri.Printf( PRINT_ALL, "Warning: stencil shadows and overdraw measurement are mutually exclusive\n" ); ri.Cvar_Set( "r_measureOverdraw", "0" ); - r_measureOverdraw->modified = qfalse; } + else if ( r_stereoEnabled->integer >= 2 ) + { + ri.Printf( PRINT_ALL, "Warning: interlaced stereo and overdraw measurement are mutually exclusive\n" ); + ri.Cvar_Set( "r_measureOverdraw", "0" ); + } else { R_SyncRenderThread(); Index: tr_local.h =================================================================== --- tr_local.h (revision 2260) +++ tr_local.h (working copy) @@ -872,6 +872,8 @@ byte color2D[4]; qboolean vertexes2D; // shader needs to be finished trRefEntity_t entity2D; // currentEntity will point at this when doing 2D rendering + + qboolean doneStereoInterlace; } backEndState_t; /* @@ -1707,5 +1710,7 @@ void R_DoneFreeType( void ); void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font); +// Stereo Interlace +void RB_InterlaceStencil( int gliWindowWidth, int gliWindowHeight ); #endif //TR_LOCAL_H