Index: tr_backend.c =================================================================== --- tr_backend.c (revision 2260) +++ tr_backend.c (working copy) @@ -507,9 +507,63 @@ } 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; + + 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=0; gliYinteger == 2) { + if (backEnd.projection2D == qfalse) { + if (backEnd.viewParms.stereoFrame == STEREO_LEFT) qglStencilFunc(GL_NOTEQUAL, 1, 1); + else if (backEnd.viewParms.stereoFrame == STEREO_RIGHT) qglStencilFunc(GL_EQUAL, 1, 1); + else qglStencilFunc(GL_ALWAYS, 1, 1); + } + }*/ +} + + #define MAC_EVENT_PUMP_MSEC 5 /* @@ -691,6 +745,9 @@ // add light flares on lights that aren't obscured RB_RenderFlares(); + + // Interlace screen + RB_InterlaceStencil(glConfig.vidWidth, glConfig.vidHeight); } @@ -711,6 +768,9 @@ void RB_SetGL2D (void) { backEnd.projection2D = qtrue; + if (r_stereoEnabled->integer == 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 ); @@ -806,6 +866,8 @@ qglTexCoord2f ( 0.5f / cols, ( rows - 0.5f ) / rows ); qglVertex2f (x, y+h); qglEnd (); + + RB_RestoreInterlace(); } void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) { @@ -922,6 +984,8 @@ tess.texCoords[ numVerts + 3 ][0][0] = cmd->s1; tess.texCoords[ numVerts + 3 ][0][1] = cmd->t2; + RB_RestoreInterlace(); + return (const void *)(cmd + 1); } @@ -961,9 +1025,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 ); @@ -1026,6 +1098,8 @@ qglEnd(); } + RB_RestoreInterlace(); + qglFinish(); end = ri.Milliseconds(); @@ -1079,6 +1153,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 +1197,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,8 @@ void R_DoneFreeType( void ); void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font); +// Stereo Interlace +void RB_RestoreInterlace( void ); +void RB_InterlaceStencil( int gliWindowWidth, int gliWindowHeight ); #endif //TR_LOCAL_H