void D3D9Renderer::_RS_Render_Shadows() { SGRX_Scene* scene = m_currentScene; for( size_t pass_id = 0; pass_id < m_renderPasses.size(); ++pass_id ) { // Only shadow passes if( m_renderPasses[ pass_id ].type != RPT_SHADOWS ) continue; for( size_t light_id = 0; light_id < scene->m_lights.size(); ++light_id ) { Mat4 m_world_view, m_inv_view; SGRX_Light* L = scene->m_lights.item( light_id ).key; if( !L->enabled || !L->shadowTexture || !L->shadowTexture->m_isRenderTexture ) continue; /* CULL */ _RS_Cull_SpotLight_MeshList( scene, L ); D3D9RenderTexture* RT = (D3D9RenderTexture*) L->shadowTexture.item; m_dev->SetRenderTarget( 0, RT->CS ); m_dev->SetDepthStencilSurface( RT->DSS ); m_dev->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0 ); VS_SetMat4( 4, L->projMatrix ); VS_SetMat4( 12, L->viewMatrix ); m_inv_view = L->viewMatrix; m_inv_view.Transpose(); PS_SetMat4( 0, m_inv_view ); PS_SetMat4( 4, L->projMatrix ); for( size_t miid = 0; miid < m_visible_spot_meshes.size(); ++miid ) { SGRX_MeshInstance* MI = m_visible_spot_meshes[ miid ]; if( !MI->mesh || !MI->enabled ) continue; /* mesh not added / instance not enabled */ D3D9Mesh* M = (D3D9Mesh*) MI->mesh.item; if( !M->m_vertexDecl ) continue; /* mesh not initialized */ D3D9VertexDecl* VD = (D3D9VertexDecl*) M->m_vertexDecl.item; /* if (transparent & want solid) or (solid & want transparent), skip */ if( MI->transparent || MI->decal ) continue; MI_ApplyConstants( MI ); m_world_view.Multiply( MI->matrix, L->viewMatrix ); VS_SetMat4( 0, m_world_view ); VS_SetMat4( 8, MI->matrix ); m_dev->SetRenderState( D3DRS_CULLMODE, M->m_dataFlags & MDF_NOCULL ? D3DCULL_NONE : D3DCULL_CCW ); m_dev->SetVertexDeclaration( VD->m_vdecl ); m_dev->SetStreamSource( 0, M->m_VB, 0, VD->m_info.size ); m_dev->SetIndices( M->m_IB ); for( size_t part_id = 0; part_id < M->m_meshParts.size(); ++part_id ) { SGRX_MeshPart* MP = &M->m_meshParts[ part_id ]; SGRX_Material* MTL = MP->material; if( !MTL ) continue; SGRX_SurfaceShader* SSH = MTL->shader; if( !SSH ) continue; if( MTL->transparent ) continue; SGRX_IVertexShader* VSH = MI->skin_matrices.size() ? SSH->m_skinVertexShaders[ pass_id ] : SSH->m_basicVertexShaders[ pass_id ]; if( !VSH ) continue; SGRX_IPixelShader* SHD = SSH->m_pixelShaders[ pass_id ]; if( !SHD ) continue; if( MP->indexCount < 3 ) continue; SetVertexShader( VSH ); SetPixelShader( SHD ); for( int tex_id = 0; tex_id < NUM_MATERIAL_TEXTURES; ++tex_id ) SetTexture( tex_id, MTL->textures[ tex_id ] ); m_dev->DrawIndexedPrimitive( M->m_dataFlags & MDF_TRIANGLESTRIP ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST, MP->vertexOffset, 0, MP->vertexCount, MP->indexOffset, M->m_dataFlags & MDF_TRIANGLESTRIP ? MP->indexCount - 2 : MP->indexCount / 3 ); m_stats.numDrawCalls++; m_stats.numSDrawCalls++; } } } } }