void IGame::OnDrawScene( SGRX_IRenderControl* ctrl, SGRX_RenderScene& info )
{
#define RT_MAIN 0xfff0
#define RT_HBLUR 0xfff1
#define RT_VBLUR 0xfff2
#define RT_HBLUR2 0xfff3
#define RT_VBLUR2 0xfff4
#define RT_HPASS 0xfff5
#define RT_DEPTH 0xfff6
// preserve state
Mat4 viewMtx = g_BatchRenderer->viewMatrix;
// shortcuts
SGRX_Scene* scene = info.scene;
BatchRenderer& br = GR2D_GetBatchRenderer();
int W = GR_GetWidth();
int H = GR_GetHeight();
int W4 = TMAX( W / 4, 1 ), H4 = TMAX( H / 4, 1 );
int W16 = TMAX( W4 / 4, 1 ), H16 = TMAX( H4 / 4, 1 );
// load shaders
PixelShaderHandle pppsh_final = GR_GetPixelShader( "sys_pp_final" );
PixelShaderHandle pppsh_highpass = GR_GetPixelShader( "sys_pp_highpass" );
PixelShaderHandle pppsh_blur = GR_GetPixelShader( "sys_pp_blur" );
GR_PreserveResource( pppsh_final );
GR_PreserveResource( pppsh_highpass );
GR_PreserveResource( pppsh_blur );
// initial actions
ctrl->RenderShadows( scene, 0 );
ctrl->SortRenderItems( scene );
// prepare render targets
TextureHandle rttMAIN, rttHPASS, rttHBLUR, rttVBLUR, rttHBLUR2, rttVBLUR2, rttDEPTH;
DepthStencilSurfHandle dssMAIN;
if( info.enablePostProcessing )
{
rttMAIN = GR_GetRenderTarget( W, H, RT_FORMAT_COLOR_HDR16, RT_MAIN );
rttDEPTH = GR_GetRenderTarget( W, H, RT_FORMAT_COLOR_HDR16, RT_DEPTH );
rttHPASS = GR_GetRenderTarget( W, H, RT_FORMAT_COLOR_HDR16, RT_HPASS );
rttHBLUR = GR_GetRenderTarget( W4, H, RT_FORMAT_COLOR_HDR16, RT_HBLUR );
rttVBLUR = GR_GetRenderTarget( W4, H4, RT_FORMAT_COLOR_HDR16, RT_VBLUR );
rttHBLUR2 = GR_GetRenderTarget( W16, H4, RT_FORMAT_COLOR_HDR16, RT_HBLUR2 );
rttVBLUR2 = GR_GetRenderTarget( W16, H16, RT_FORMAT_COLOR_HDR16, RT_VBLUR2 );
dssMAIN = GR_GetDepthStencilSurface( W, H, RT_FORMAT_COLOR_HDR16, RT_MAIN );
GR_PreserveResource( rttMAIN );
GR_PreserveResource( rttDEPTH );
GR_PreserveResource( rttHPASS );
GR_PreserveResource( rttHBLUR );
GR_PreserveResource( rttVBLUR );
GR_PreserveResource( rttHBLUR2 );
GR_PreserveResource( rttVBLUR2 );
GR_PreserveResource( dssMAIN );
ctrl->SetRenderTargets( dssMAIN, SGRX_RT_ClearAll, 0, 0, 1, rttDEPTH );
ctrl->RenderTypes( scene, 0, 1, SGRX_TY_Solid );
}
// draw things
ctrl->SetRenderTargets( dssMAIN, SGRX_RT_ClearAll, 0, 0, 1, rttMAIN );
if( info.viewport )
GR2D_SetViewport( info.viewport->x0, info.viewport->y0, info.viewport->x1, info.viewport->y1 );
ctrl->RenderTypes( scene, 1, 1, SGRX_TY_Solid );
ctrl->RenderTypes( scene, 3, 4, SGRX_TY_Solid );
ctrl->RenderTypes( scene, 1, 1, SGRX_TY_Decal );
ctrl->RenderTypes( scene, 3, 4, SGRX_TY_Decal );
ctrl->RenderTypes( scene, 1, 1, SGRX_TY_Transparent );
ctrl->RenderTypes( scene, 3, 4, SGRX_TY_Transparent );
if( info.postdraw )
{
GR2D_SetViewMatrix( scene->camera.mView * scene->camera.mProj );
info.postdraw->PostDraw();
}
// post-process
GR2D_SetViewMatrix( Mat4::CreateUI( 0, 0, 1, 1 ) );
if( info.enablePostProcessing )
{
br.Reset();
br.ShaderData.push_back( V4(0) );
float spread = 3.5f;
ctrl->SetRenderTargets( NULL, SGRX_RT_ClearAll, 0, 0, 1, rttHPASS );
br.SetTexture( rttMAIN ).SetShader( pppsh_highpass ).Quad( 0, 0, 1, 1 ).Flush();
br.ShaderData[0] = V4( 0, 0, safe_fdiv( spread, W ), 0 );
ctrl->SetRenderTargets( NULL, SGRX_RT_ClearAll, 0, 0, 1, rttHBLUR );
br.SetTexture( rttHPASS ).SetShader( pppsh_blur ).Quad( 0, 0, 1, 1 ).Flush();
br.ShaderData[0] = V4( 0, 0, 0, safe_fdiv( spread, H ) );
ctrl->SetRenderTargets( NULL, SGRX_RT_ClearAll, 0, 0, 1, rttVBLUR );
br.SetTexture( rttHBLUR ).SetShader( pppsh_blur ).Quad( 0, 0, 1, 1 ).Flush();
br.ShaderData[0] = V4( 0, 0, safe_fdiv( spread, W4 ), 0 );
ctrl->SetRenderTargets( NULL, SGRX_RT_ClearAll, 0, 0, 1, rttHBLUR2 );
br.SetTexture( rttVBLUR ).SetShader( pppsh_blur ).Quad( 0, 0, 1, 1 ).Flush();
br.ShaderData[0] = V4( 0, 0, 0, safe_fdiv( spread, H4 ) );
ctrl->SetRenderTargets( NULL, SGRX_RT_ClearAll, 0, 0, 1, rttVBLUR2 );
br.SetTexture( rttHBLUR2 ).SetShader( pppsh_blur ).Quad( 0, 0, 1, 1 ).Flush();
ctrl->SetRenderTargets( NULL, 0, 0, 0, 1 );
br.SetTexture( 0, rttMAIN )
.SetTexture( 2, rttVBLUR )
.SetTexture( 3, rttVBLUR2 )
.SetTexture( 4, rttDEPTH ).SetShader( pppsh_final ).VPQuad( info.viewport ).Flush();
}
else
{
ctrl->SetRenderTargets( NULL, 0, 0, 0, 1 );
br.Reset().SetTexture( rttMAIN ).VPQuad( info.viewport ).Flush();
}
// debug rendering from camera viewpoint and optional depth clipping
if( info.debugdraw )
{
ctrl->SetRenderTargets( dssMAIN, 0, 0, 0, 1 );
if( info.viewport )
GR2D_SetViewport( info.viewport->x0, info.viewport->y0, info.viewport->x1, info.viewport->y1 );
GR2D_SetViewMatrix( scene->camera.mView * scene->camera.mProj );
info.debugdraw->DebugDraw();
if( info.viewport )
GR2D_UnsetViewport();
ctrl->SetRenderTargets( NULL, 0, 0, 0, 1 );
}
GR2D_SetViewMatrix( viewMtx );
}
Comments