Пример #1
0
        public void Render(Light light)
        {
            LightVaos vaos = GetVaosForLight(light);

            if (!vaos.Enabled)
            {
                return;
            }

            _engine.Device.RasterizerState   = _engine.Rs;
            _engine.Device.DepthStencilState = DepthStencilState.None;
            _engine.Device.DepthStencilState = light.ShadowType == ShadowType.Occluded
                ? _dsOccludedShadow
                : DepthStencilState.None;

            if (light.CastsShadows)
            {
                _fxShadowParamLightPosition.SetValue(light.Position);
                _fxShadowParamLightRadius.SetValue(light.Radius);

                // Draw shadows.
                DynamicVao shadowVao = vaos.ShadowVao;
                _engine.Device.BlendState = _bsShadow;
                _engine.Device.SetVertexArrayObject(shadowVao);
                _fxShadowTech.Passes[0].Apply();
                _engine.Device.DrawIndexedPrimitives(shadowVao.PrimitiveTopology, 0, 0, shadowVao.PrimitiveCount);

                // Draw shadows borders if debugging.
                if (_engine.Debug)
                {
                    _engine.Device.RasterizerState = _engine.RsDebug;
                    _engine.Device.BlendState      = BlendState.Opaque;
                    _fxShadowTechDebug.Passes[0].Apply();
                    _engine.Device.DrawIndexedPrimitives(shadowVao.PrimitiveTopology, 0, 0, shadowVao.PrimitiveCount);
                }
            }

            // Draw hulls.
            bool isShadowTypeSolid = light.ShadowType == ShadowType.Solid;

            if (light.CastsShadows || isShadowTypeSolid)
            {
                if (light.ShadowType == ShadowType.Occluded)
                {
                    _engine.Device.DepthStencilState = _dsOccludedHull;
                }

                DynamicVao hullVao = vaos.HullVao;
                _engine.Device.RasterizerState = _engine.Rs;
                _engine.Device.BlendState      = _bsHull;
                _fxHullParamVp.SetValue(_engine.Camera.ViewProjection);
                _fxHullParamColor.SetValue(isShadowTypeSolid ? TransparentColor : WhiteColor);
                _engine.Device.SetVertexArrayObject(hullVao);
                _fxHullTech.Passes[0].Apply();
                _engine.Device.DrawIndexedPrimitives(hullVao.PrimitiveTopology, 0, 0, hullVao.PrimitiveCount);
            }
        }
Пример #2
0
        private LightVaos GetVaosForLight(Light light)
        {
            if (!_lightsVaos.TryGetValue(light, out LightVaos lightVaos))
            {
                lightVaos          = new LightVaos();
                _lightsVaos[light] = lightVaos;
            }

            if (light.Dirty || _engine.Hulls.Dirty)
            {
                BuildVaosForLight(light, lightVaos);
            }

            return(lightVaos);
        }
Пример #3
0
        private void BuildVaosForLight(Light light, LightVaos lightVaos)
        {
            _hullVertices.Clear();
            _shadowVertices.Clear();
            _shadowIndices.Clear();
            _hullIndices.Clear();

            int numSegments       = 0;
            int shadowIndexOffset = 0;
            int hullIndexOffset   = 0;
            int hullCount         = _engine.Hulls.Count;

            for (int i = 0; i < hullCount; i++)
            {
                Hull hull = _engine.Hulls[i];
                if (!hull.Enabled ||
                    !hull.Valid ||
                    light.IgnoredHulls.Contains(hull) ||
                    !light.Intersects(hull))
                {
                    continue;
                }

                Polygon points = hull.WorldPoints;

                Vector2 prevPoint = points.Items[points.Count - 1];

                int pointCount = points.Count;
                numSegments += pointCount;
                for (int j = 0; j < pointCount; j++)
                {
                    Vector2 currentPoint = points.Items[j];

                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(0.0f, 0.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(1.0f, 0.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(0.0f, 1.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(1.0f, 1.0f)));

                    _shadowIndices.Add(shadowIndexOffset * 4 + 0);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 1);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 2);

                    _shadowIndices.Add(shadowIndexOffset * 4 + 1);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 3);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 2);

                    prevPoint = currentPoint;
                    shadowIndexOffset++;
                }

                _hullVertices.AddRange(hull.WorldPoints);

                int indexCount = hull.Indices.Count;
                for (int j = 0; j < indexCount; j++)
                {
                    _hullIndices.Add(hull.Indices.Items[j] + hullIndexOffset);
                }
                hullIndexOffset += pointCount;
            }

            lightVaos.Enabled = numSegments > 0;
            if (!lightVaos.Enabled)
            {
                return;
            }

            if (lightVaos.ShadowVao == null)
            {
                lightVaos.ShadowVao = DynamicVao.New(
                    _engine.Device,
                    VertexShadow.Layout,
                    PrimitiveType.TriangleList,
                    _shadowVertices.Count,
                    _shadowIndices.Count,
                    useIndices: true);
                lightVaos.HullVao = DynamicVao.New(
                    _engine.Device,
                    VertexPosition2.Layout,
                    PrimitiveType.TriangleList,
                    _hullVertices.Count,
                    _hullIndices.Count,
                    useIndices: true);
            }

            lightVaos.ShadowVao.SetVertices(_shadowVertices);
            lightVaos.ShadowVao.SetIndices(_shadowIndices);
            lightVaos.HullVao.SetVertices(_hullVertices);
            lightVaos.HullVao.SetIndices(_hullIndices);
        }