コード例 #1
0
        public void RenderOutlines(IBatchContainer container, int layer, bool showLights, Color?lineColor = null, Color?lightColor = null)
        {
            using (var group = BatchGroup.New(container, layer)) {
                using (var gb = GeometryBatch.New(group, 0, IlluminantMaterials.DebugOutlines)) {
                    VisualizerLineWriterInstance.Batch = gb;
                    VisualizerLineWriterInstance.Color = lineColor.GetValueOrDefault(Color.White);

                    foreach (var lo in Environment.Obstructions)
                    {
                        lo.GenerateLines(VisualizerLineWriterInstance);
                    }

                    VisualizerLineWriterInstance.Batch = null;
                }

                int i = 0;

                if (showLights)
                {
                    foreach (var lightSource in Environment.LightSources)
                    {
                        var cMax = lightColor.GetValueOrDefault(Color.White);
                        var cMin = cMax * 0.25f;

                        using (var gb = GeometryBatch.New(group, i + 1, IlluminantMaterials.DebugOutlines)) {
                            gb.AddFilledRing(lightSource.Position, 0f, 2f, cMax, cMax);
                            gb.AddFilledRing(lightSource.Position, lightSource.RampStart - 1f, lightSource.RampStart + 1f, cMax, cMax);
                            gb.AddFilledRing(lightSource.Position, lightSource.RampEnd - 1f, lightSource.RampEnd + 1f, cMin, cMin);
                        }

                        i += 1;
                    }
                }
            }
        }
コード例 #2
0
        public override void Draw(Squared.Render.Frame frame)
        {
            const float LightmapScale = 1f;

            LightmapMaterials.ViewportScale    = new Vector2(1f / LightmapScale);
            LightmapMaterials.ProjectionMatrix = Matrix.CreateOrthographicOffCenter(
                0, Width,
                Height, 0,
                0, 1
                );

            ClearBatch.AddNew(frame, 0, Game.ScreenMaterials.Clear, clearColor: Color.Black);

            Renderer.RenderLighting(frame, frame, 1);

            using (var bg = BatchGroup.New(frame, 2)) {
                var dc = new BitmapDrawCall(TestImage, new Vector2(0, 550), 0.55f);

                using (var bb = BitmapBatch.New(bg, 0, Renderer.Materials.ScreenSpaceBitmap))
                    bb.Add(ref dc);

                dc.Position.X += 600;
                dc.Textures    = new TextureSet(dc.Texture, RampTexture);

                using (var bb2 = BitmapBatch.New(bg, 1, Renderer.IlluminantMaterials.ScreenSpaceRampBitmap, samplerState2: SamplerState.LinearClamp))
                    bb2.Add(ref dc);
            }

            if (ShowOutlines)
            {
                Renderer.RenderOutlines(frame, 2, true);
            }
        }
コード例 #3
0
        public ImperativeRenderer MakeSubgroup(bool nextLayer = true, Action <DeviceManager, object> before = null, Action <DeviceManager, object> after = null, object userData = null)
        {
            var result = this;
            var group  = BatchGroup.New(Container, Layer, before: before, after: after, userData: userData);

            group.Dispose();
            result.Container = group;
            result.Layer     = 0;

            if (nextLayer)
            {
                Layer += 1;
            }

            return(result);
        }
コード例 #4
0
        /// <summary>
        /// Renders all light sources into the target batch container on the specified layer.
        /// </summary>
        /// <param name="frame">Necessary for bookkeeping.</param>
        /// <param name="container">The batch container to render lighting into.</param>
        /// <param name="layer">The layer to render lighting into.</param>
        /// <param name="intensityScale">A factor to scale the intensity of all light sources. You can use this to rescale the intensity of light values for HDR.</param>
        public void RenderLighting(Frame frame, IBatchContainer container, int layer, float intensityScale = 1.0f)
        {
            // FIXME
            var pointLightVertexCount = Environment.LightSources.Count * 4;
            var pointLightIndexCount  = Environment.LightSources.Count * 6;

            if (PointLightVertices.Length < pointLightVertexCount)
            {
                PointLightVertices = new PointLightVertex[1 << (int)Math.Ceiling(Math.Log(pointLightVertexCount, 2))];
            }

            if ((PointLightIndices == null) || (PointLightIndices.Length < pointLightIndexCount))
            {
                PointLightIndices = new short[pointLightIndexCount];

                int i = 0, j = 0;
                while (i < pointLightIndexCount)
                {
                    PointLightIndices[i++] = (short)(j + 0);
                    PointLightIndices[i++] = (short)(j + 1);
                    PointLightIndices[i++] = (short)(j + 3);
                    PointLightIndices[i++] = (short)(j + 1);
                    PointLightIndices[i++] = (short)(j + 2);
                    PointLightIndices[i++] = (short)(j + 3);

                    j += 4;
                }
            }

            var         needStencilClear = true;
            int         vertexOffset = 0, indexOffset = 0;
            LightSource batchFirstLightSource = null;
            BatchGroup  currentLightGroup     = null;

            int layerIndex = 0;

            using (var sortedLights = BufferPool <LightSource> .Allocate(Environment.LightSources.Count))
                using (var resultGroup = BatchGroup.New(container, layer, before: StoreScissorRect, after: RestoreScissorRect)) {
                    if (Render.Tracing.RenderTrace.EnableTracing)
                    {
                        Render.Tracing.RenderTrace.Marker(resultGroup, -9999, "Frame {0:0000} : LightingRenderer {1:X4} : Begin", frame.Index, this.GetHashCode());
                    }

                    int i          = 0;
                    var lightCount = Environment.LightSources.Count;

                    foreach (var lightSource in Environment.LightSources)
                    {
                        sortedLights.Data[i++] = lightSource;
                    }

                    Array.Sort(sortedLights.Data, 0, lightCount, LightSourceComparerInstance);

                    int lightGroupIndex = 1;

                    for (i = 0; i < lightCount; i++)
                    {
                        var lightSource = sortedLights.Data[i];

                        if (lightSource.Opacity <= 0)
                        {
                            continue;
                        }

                        if (batchFirstLightSource != null)
                        {
                            var needFlush =
                                (needStencilClear) ||
                                (batchFirstLightSource.ClipRegion.HasValue != lightSource.ClipRegion.HasValue) ||
                                (batchFirstLightSource.NeutralColor != lightSource.NeutralColor) ||
                                (batchFirstLightSource.Mode != lightSource.Mode) ||
                                (batchFirstLightSource.RampMode != lightSource.RampMode) ||
                                (batchFirstLightSource.RampTexture != lightSource.RampTexture) ||
                                (batchFirstLightSource.RampTextureFilter != lightSource.RampTextureFilter);

                            if (needFlush)
                            {
                                if (Render.Tracing.RenderTrace.EnableTracing)
                                {
                                    Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : Point Light Flush ({2} point(s))", frame.Index, this.GetHashCode(), PointLightBatchBuffer.Count);
                                }
                                FlushPointLightBatch(ref currentLightGroup, ref batchFirstLightSource, ref layerIndex);
                                indexOffset = 0;
                            }
                        }

                        if (batchFirstLightSource == null)
                        {
                            batchFirstLightSource = lightSource;
                        }
                        if (currentLightGroup == null)
                        {
                            currentLightGroup = BatchGroup.New(resultGroup, lightGroupIndex++, before: RestoreScissorRect);
                        }

                        var lightBounds = new Bounds(lightSource.Position - new Vector2(lightSource.RampEnd), lightSource.Position + new Vector2(lightSource.RampEnd));

                        Bounds clippedLightBounds;
                        if (lightSource.ClipRegion.HasValue)
                        {
                            var clipBounds = lightSource.ClipRegion.Value;
                            if (!lightBounds.Intersection(ref lightBounds, ref clipBounds, out clippedLightBounds))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            clippedLightBounds = lightBounds;
                        }

                        if (needStencilClear)
                        {
                            if (Render.Tracing.RenderTrace.EnableTracing)
                            {
                                Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : Stencil Clear", frame.Index, this.GetHashCode());
                            }
                            ClearBatch.AddNew(currentLightGroup, layerIndex++, IlluminantMaterials.ClearStencil, clearStencil: StencilFalse);
                            needStencilClear = false;
                        }

                        NativeBatch stencilBatch = null;
                        SpatialCollection <LightObstructionBase> .Sector currentSector;
                        using (var e = Environment.Obstructions.GetSectorsFromBounds(lightBounds))
                            while (e.GetNext(out currentSector))
                            {
                                var cachedSector = GetCachedSector(frame, currentSector.Index);
                                if (cachedSector.VertexCount <= 0)
                                {
                                    continue;
                                }

                                if (stencilBatch == null)
                                {
                                    if (Render.Tracing.RenderTrace.EnableTracing)
                                    {
                                        Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : Begin Stencil Shadow Batch", frame.Index, this.GetHashCode());
                                    }

                                    stencilBatch = NativeBatch.New(currentLightGroup, layerIndex++, IlluminantMaterials.Shadow, ShadowBatchSetup, lightSource);
                                    stencilBatch.Dispose();
                                    needStencilClear = true;

                                    if (Render.Tracing.RenderTrace.EnableTracing)
                                    {
                                        Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : End Stencil Shadow Batch", frame.Index, this.GetHashCode());
                                    }
                                }

                                stencilBatch.Add(new NativeDrawCall(
                                                     PrimitiveType.TriangleList, cachedSector.ObstructionVertexBuffer, 0, cachedSector.ObstructionIndexBuffer, 0, 0, cachedSector.VertexCount, 0, cachedSector.PrimitiveCount
                                                     ));
                            }

                        PointLightVertex vertex;

                        vertex.LightCenter = lightSource.Position;
                        vertex.Color       = lightSource.Color;
                        vertex.Color.W    *= (lightSource.Opacity * intensityScale);
                        vertex.Ramp        = new Vector2(lightSource.RampStart, lightSource.RampEnd);

                        vertex.Position = clippedLightBounds.TopLeft;
                        PointLightVertices[vertexOffset++] = vertex;

                        vertex.Position = clippedLightBounds.TopRight;
                        PointLightVertices[vertexOffset++] = vertex;

                        vertex.Position = clippedLightBounds.BottomRight;
                        PointLightVertices[vertexOffset++] = vertex;

                        vertex.Position = clippedLightBounds.BottomLeft;
                        PointLightVertices[vertexOffset++] = vertex;

                        var newRecord = new PointLightRecord {
                            VertexOffset = vertexOffset - 4,
                            IndexOffset  = indexOffset,
                            VertexCount  = 4,
                            IndexCount   = 6
                        };

                        if (PointLightBatchBuffer.Count > 0)
                        {
                            var oldRecord = PointLightBatchBuffer[PointLightBatchBuffer.Count - 1];

                            if (
                                (newRecord.VertexOffset == oldRecord.VertexOffset + oldRecord.VertexCount) &&
                                (newRecord.IndexOffset == oldRecord.IndexOffset + oldRecord.IndexCount)
                                )
                            {
                                oldRecord.VertexCount += newRecord.VertexCount;
                                oldRecord.IndexCount  += newRecord.IndexCount;
                                PointLightBatchBuffer[PointLightBatchBuffer.Count - 1] = oldRecord;
                            }
                            else
                            {
                                PointLightBatchBuffer.Add(newRecord);
                            }
                        }
                        else
                        {
                            PointLightBatchBuffer.Add(newRecord);
                        }

                        indexOffset += 6;
                    }

                    if (PointLightBatchBuffer.Count > 0)
                    {
                        if (Render.Tracing.RenderTrace.EnableTracing)
                        {
                            Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : Point Light Flush ({2} point(s))", frame.Index, this.GetHashCode(), PointLightBatchBuffer.Count);
                        }

                        FlushPointLightBatch(ref currentLightGroup, ref batchFirstLightSource, ref layerIndex);
                    }

                    if (Render.Tracing.RenderTrace.EnableTracing)
                    {
                        Render.Tracing.RenderTrace.Marker(resultGroup, 9999, "Frame {0:0000} : LightingRenderer {1:X4} : End", frame.Index, this.GetHashCode());
                    }
                }
        }