/* * R_DrawPortals */ void R_DrawPortals( void ) { unsigned int i; if( rn.renderFlags & RF_SKYSHADOWVIEW ) { // render depth mask for skylights // TODO: rewrite this! float depthmin, depthmax; RB_GetDepthRange( &depthmin, &depthmax ); RB_ClearDepth( depthmin ); RB_Clear( GL_DEPTH_BUFFER_BIT, 0, 0, 0, 0 ); if( rn.portalmasklist && rn.portalmasklist->numDrawSurfs ) { RB_SetShaderStateMask( ~0, GLSTATE_DEPTHWRITE | GLSTATE_NO_COLORWRITE | GLSTATE_OFFSET_FILL | GLSTATE_DEPTHFUNC_GT ); RB_FlipFrontFace(); RB_DepthRange( depthmax, depthmax ); R_DrawPortalSurfaces( rn.portalmasklist ); RB_SetShaderStateMask( ~0, GLSTATE_DEPTHWRITE | GLSTATE_NO_COLORWRITE | GLSTATE_OFFSET_FILL ); RB_FlipFrontFace(); RB_DepthRange( depthmin, depthmax ); } RB_ClearDepth( depthmax ); return; } if( rn.renderFlags & ( RF_MIRRORVIEW | RF_LIGHTVIEW | RF_PORTALVIEW ) ) { return; } if( rn.viewcluster == -1 ) { return; } R_DrawPortalsDepthMask(); if( rn.skyportalSurface ) { // render skyportal portalSurface_t *ps = rn.skyportalSurface; R_DrawSkyportal( ps->entity, ps->skyPortal ); } else { // FIXME: move this? // render sky dome that writes to depth R_DrawDepthSkySurf(); } // render regular portals for( i = 0; i < rn.numPortalSurfaces; i++ ) { portalSurface_t ps = rn.portalSurfaces[i]; if( !ps.skyPortal ) { R_DrawPortalSurface( &ps ); rn.portalSurfaces[i] = ps; } } }
/* * R_DrawPortalsDepthMask * * Renders portal or sky surfaces from the BSP tree to depth buffer. Each rendered pixel * receives the depth value of 1.0, everything else is cleared to 0.0. * * The depth buffer is then preserved for portal render stage to minimize overdraw. */ static void R_DrawPortalsDepthMask( void ) { float depthmin, depthmax; if( !rn.portalmasklist || !rn.portalmasklist->numDrawSurfs ) { return; } RB_GetDepthRange( &depthmin, &depthmax ); RB_ClearDepth( depthmin ); RB_Clear( GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT, 0, 0, 0, 0 ); RB_SetShaderStateMask( ~0, GLSTATE_DEPTHWRITE | GLSTATE_DEPTHFUNC_GT | GLSTATE_NO_COLORWRITE ); RB_DepthRange( depthmax, depthmax ); R_DrawPortalSurfaces( rn.portalmasklist ); RB_DepthRange( depthmin, depthmax ); RB_ClearDepth( depthmax ); }
/* * RB_Clear */ void RB_Clear( int bits, float r, float g, float b, float a ) { // this is required for glClear(GL_DEPTH_BUFFER_BIT) to work if( bits & GL_DEPTH_BUFFER_BIT ) RB_SetState( GLSTATE_DEPTHWRITE ); if( bits & GL_STENCIL_BUFFER_BIT ) qglClearStencil( 128 ); if( bits & GL_COLOR_BUFFER_BIT ) qglClearColor( r, g, b, a ); qglClear( bits ); RB_DepthRange( 0, 1 ); }
/* * RB_Clear */ void RB_Clear( int bits, float r, float g, float b, float a ) { int state = rb.gl.state; if( bits & GL_DEPTH_BUFFER_BIT ) state |= GLSTATE_DEPTHWRITE; if( bits & GL_STENCIL_BUFFER_BIT ) qglClearStencil( 128 ); if( bits & GL_COLOR_BUFFER_BIT ) { state &= ~GLSTATE_NO_COLORWRITE; qglClearColor( r, g, b, a ); } RB_SetState( state ); qglClear( bits ); RB_DepthRange( 0.0f, 1.0f ); }