| 97 | } |
| 98 | |
| 99 | void PlanarShadowEffect::Draw(std::shared_ptr<GraphicsEngine> const& engine, |
| 100 | PVWUpdater& pvwMatrices) |
| 101 | { |
| 102 | // Save the global state, to be restored later. |
| 103 | std::shared_ptr<BlendState> saveBState = engine->GetBlendState(); |
| 104 | std::shared_ptr<DepthStencilState> saveDSState = engine->GetDepthStencilState(); |
| 105 | |
| 106 | // Get the camera to store post-world transformations. |
| 107 | std::shared_ptr<Camera> camera = pvwMatrices.GetCamera(); |
| 108 | |
| 109 | // Draw the the shadow caster. |
| 110 | engine->Draw(mCasterVisuals); |
| 111 | |
| 112 | for (size_t i = 0; i < mPlaneVisuals.size(); ++i) |
| 113 | { |
| 114 | auto const& plane = mPlaneVisuals[i]; |
| 115 | uint32_t reference = static_cast<uint32_t>(i + 1); |
| 116 | |
| 117 | // Enable default depth state. Enable the stencil state so that the |
| 118 | // shadow can be clipped by the plane. The stencil values are set |
| 119 | // whenever the corresponding plane pixels are visible. No blending |
| 120 | // is used in this pass. |
| 121 | mDSPass0->reference = reference; |
| 122 | engine->SetDepthStencilState(mDSPass0); |
| 123 | engine->SetBlendState(saveBState); |
| 124 | engine->Draw(plane); |
| 125 | |
| 126 | // Disable the depth buffer reading so that no depth-buffer fighting |
| 127 | // occurs. The drawing of pixels is controlled solely by the stencil |
| 128 | // value. Blend the shadow color with the pixels drawn on the |
| 129 | // projection plane. |
| 130 | mDSPass1->reference = reference; |
| 131 | engine->SetDepthStencilState(mDSPass1); |
| 132 | engine->SetBlendState(mShadowBlend); |
| 133 | |
| 134 | // Set the projection matrix relative to the projector (light). |
| 135 | Matrix4x4<float> projectionMatrix{}; |
| 136 | if (!GetProjectionMatrix(i, projectionMatrix)) |
| 137 | { |
| 138 | // The shadow should not be cast because the caster is on the far |
| 139 | // side of the world plane. |
| 140 | continue; |
| 141 | } |
| 142 | |
| 143 | camera->SetPreViewMatrix(projectionMatrix); |
| 144 | |
| 145 | // Draw the caster again, but temporarily use a material effect so |
| 146 | // that the shadow color is blended onto the plane. TODO: This |
| 147 | // drawing pass should use a visible set relative to the projector so |
| 148 | // that the objects thare are out of view of the camera (not in the |
| 149 | // camera's visible set) can cast shadows. |
| 150 | for (size_t j = 0; j < mCasterVisuals.size(); ++j) |
| 151 | { |
| 152 | // Save the currently attached visual effect. |
| 153 | auto const& visual = mCasterVisuals[j]; |
| 154 | mSaveVisualEffects[j] = visual->GetEffect(); |
| 155 | |
| 156 | // Draw the shadow using the current plane's shadow color. |
nothing calls this directly
no test coverage detected