Esempio n. 1
0
        private void VertexPrimitiveCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            m_Surface.Data.Clear();

            VertexPrimitive vertexPrimitive = (VertexPrimitive)VertexPrimitiveCombo.SelectedIndex;

            m_Surface.VertexPrimitive = vertexPrimitive;
            m_Surface.UseIndices      = false;

            Random rand            = new Random();
            string descriptionText = string.Empty;

            switch (vertexPrimitive)
            {
            case VertexPrimitive.Points:
            {
                descriptionText = "Each vertex represents a 3d point";

                m_Surface.FrameMode = SurfaceFrameMode.Dots;

                for (int i = 0; i < 10000; i++)
                {
                    m_Surface.Data.AddValue(rand.Next(100),
                                            rand.Next(100),
                                            rand.Next(100));
                }
            }
            break;

            case VertexPrimitive.Lines:
            {
                descriptionText = "Each consecutive pair of vertices represents a line segment";

                m_Surface.FrameMode = SurfaceFrameMode.Dots;

                for (int i = 0; i < 200; i++)
                {
                    m_Surface.Data.AddValue(rand.Next(100),
                                            rand.Next(100),
                                            rand.Next(100));

                    m_Surface.Data.AddValue(rand.Next(100),
                                            rand.Next(100),
                                            rand.Next(100));
                }
            }
            break;

            case VertexPrimitive.LineLoop:
            case VertexPrimitive.LineStrip:
            {
                descriptionText = "Adjacent vertices are connected with a line segment";

                for (int i = 0; i < 5; i++)
                {
                    m_Surface.Data.AddValue(rand.Next(100),
                                            rand.Next(100),
                                            rand.Next(100));
                }
            }
            break;

            case VertexPrimitive.Triangles:
            {
                descriptionText = "Each three consequtive vertices are considered a triangle";

                m_Surface.FrameMode = SurfaceFrameMode.Mesh;

                NVector3DD top   = new NVector3DD(0.5, 1, 0.5);
                NVector3DD baseA = new NVector3DD(0, 0, 0);
                NVector3DD baseB = new NVector3DD(1, 0, 0);
                NVector3DD baseC = new NVector3DD(1, 0, 1);
                NVector3DD baseD = new NVector3DD(0, 0, 1);

                m_Surface.Data.AddValue(top);
                m_Surface.Data.AddValue(baseA);
                m_Surface.Data.AddValue(baseB);

                m_Surface.Data.AddValue(top);
                m_Surface.Data.AddValue(baseB);
                m_Surface.Data.AddValue(baseC);

                m_Surface.Data.AddValue(top);
                m_Surface.Data.AddValue(baseC);
                m_Surface.Data.AddValue(baseD);

                m_Surface.Data.AddValue(top);
                m_Surface.Data.AddValue(baseD);
                m_Surface.Data.AddValue(baseA);
            }
            break;

            case VertexPrimitive.TriangleStrip:
            {
                descriptionText = "A series of connected triangles that share common vertices";

                m_Surface.FrameMode = SurfaceFrameMode.Mesh;

                NVector3DD A = new NVector3DD(0, 0, 0);
                NVector3DD B = new NVector3DD(1, 0, 0);
                NVector3DD C = new NVector3DD(0, 1, 1);
                NVector3DD D = new NVector3DD(1, 1, 1);

                m_Surface.Data.AddValue(A);
                m_Surface.Data.AddValue(B);
                m_Surface.Data.AddValue(C);
                m_Surface.Data.AddValue(D);
            }
            break;

            case VertexPrimitive.TriangleFan:
            {
                descriptionText = "A series of connected triangles that share a common vertex";

                m_Surface.FrameMode = SurfaceFrameMode.Mesh;

                m_Surface.Data.AddValue(0, 100, 0);

                int steps = 10;

                for (int i = 0; i < 3000; i++)
                {
                    double angle = i * 2 * Math.PI / steps;

                    m_Surface.Data.AddValue(Math.Cos(angle) * 100,
                                            0,
                                            Math.Sin(angle) * 100);
                }
            }
            break;

            case VertexPrimitive.Quads:
            {
                descriptionText = "Each for consecutive vertices form a quad";

                m_Surface.FrameMode = SurfaceFrameMode.Mesh;

                NVector3DD A = new NVector3DD(0, 0, 0);
                NVector3DD B = new NVector3DD(1, 0, 0);
                NVector3DD C = new NVector3DD(0, 1, 1);
                NVector3DD D = new NVector3DD(1, 1, 1);


                m_Surface.Data.AddValue(A);
                m_Surface.Data.AddValue(B);
                m_Surface.Data.AddValue(D);
                m_Surface.Data.AddValue(C);
            }
            break;

            case VertexPrimitive.QuadStrip:
            {
                descriptionText = "A series of connected quads that share common vertices";

                m_Surface.FrameMode = SurfaceFrameMode.Mesh;

                NVector3DD A = new NVector3DD(0, 0, 0);
                NVector3DD B = new NVector3DD(1, 0, 0);
                NVector3DD C = new NVector3DD(0, 1, 1);
                NVector3DD D = new NVector3DD(1, 1, 1);
                NVector3DD E = new NVector3DD(0, 2, 2);
                NVector3DD F = new NVector3DD(1, 2, 2);


                m_Surface.Data.AddValue(A);
                m_Surface.Data.AddValue(B);
                m_Surface.Data.AddValue(C);
                m_Surface.Data.AddValue(D);
                m_Surface.Data.AddValue(E);
                m_Surface.Data.AddValue(F);
            }

            break;
            }

            nChartControl1.Labels[0].Text = "Vertex Surface<br/><font size='10pt'>" + descriptionText + "</font>";

            nChartControl1.Refresh();
        }
        /// <summary>
        /// Generates the shadow map to be used when rendering this light.
        /// </summary>
        /// <remarks>If this instance is not to cast shadows the shadow map is cleared.</remarks>
        /// <param name="renderSystem">The render system to render with.</param>
        /// <param name="shadowMap">The shadow map to render on</param>
        protected virtual void GenerateShadowMap(DeferredRenderSystem renderSystem, RenderTarget2D shadowMap)
        {
            RenderTarget2D intermediateShadowMap = renderSystem.RenderTargets.GetTemporaryRenderTarget(SurfaceFormat.Color); // Intermediate map used for selective sampling
            RectangleF     lightDrawBounds       = this.GetWorldDrawBounds();

            renderSystem.GraphicsDevice.SetRenderTarget(shadowMap);
            renderSystem.ClearCurrentRenderTarget(Color.White); // Clear the core shadow map

            // Only render the shadows if we are to cast them
            if (this.CastsShadows)
            {
                // Render the shadow caused by each object within the lights range
                List <SpriteBase> objectList = this.World.GetSpriteObjectsInArea(lightDrawBounds).Where(currObj => (currObj.RenderOptions & SpriteRenderOptions.CastsShadows) != 0).OrderBy(s => s.LayerDepth).ToList();

                if (objectList.Count > 0)
                {
                    int  lastLayerDepth      = 0;
                    int  lastLayerDepthIndex = 0;
                    bool renderedShadow      = false; // This is used so that we don't bother occluding objects if we didn't even render anything

                    lastLayerDepth = (int)objectList[0].LayerDepth;

                    for (int objectIndex = 0; objectIndex < objectList.Count; objectIndex++)
                    {
                        SpriteBase currObj           = objectList[objectIndex];
                        RectangleF spriteWorldBounds = currObj.SpriteWorldBounds;

                        // If the object we found doesn't cast shadows (or we're inside it), skip it
                        if (spriteWorldBounds.Contains(base.Position))
                        {
                            continue;
                        }

                        this.shadowMapShader.ConfigureShader(renderSystem); // Configure the shader
                        this.shadowMapShader.GetParameter("viewProjection").SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem));
                        this.shadowMapShader.GetParameter("cameraPosition").SetValue(renderSystem.GameCamera.PixelPosition);

                        // If we switched light planes remove occlusion from all previous objects
                        if (lastLayerDepth != (int)currObj.LayerDepth)
                        {
                            // Only occlude if we actually rendered something
                            if (renderedShadow)
                            {
                                // Loop through all the objects between the last layer index and the current index
                                for (int clearObjIndex = lastLayerDepthIndex; clearObjIndex < objectIndex; clearObjIndex++)
                                {
                                    this.ProcessSpriteDepthTransition(renderSystem, objectList[clearObjIndex]);
                                }
                            }

                            // Save the last values
                            lastLayerDepth      = (int)currObj.LayerDepth;
                            lastLayerDepthIndex = objectIndex;
                            renderedShadow      = false; // Reset this
                        }

                        // Create the shadow map caused by the current sprite
                        this.shadowMapShader.ApplyPass(0);

                        // Construct the vertex primitive to mask with
                        Vector2[] extrema;
                        if (currObj.SpriteWorldShape != null)
                        {
                            extrema = currObj.SpriteWorldShape.GetRelativeExtrema(base.Position); // Get the extrema that cause the shadow
                        }
                        else
                        {
                            extrema = spriteWorldBounds.GetRelativeExtrema(base.Position); // Get the extrema that cause the shadow
                        }

                        Vector2 widthVector  = Vector2.Normalize(extrema[0] - base.Position); // Get the vector to the first extrema
                        Vector2 heightVector = Vector2.Normalize(extrema[1] - base.Position); // Get the vector to the second extrema

                        VertexPrimitive shadowArea = new VertexPrimitive(PrimitiveType.TriangleStrip, 4);
                        shadowArea.Add(extrema[0]);
                        shadowArea.Add(extrema[1]);

                        // Let's extend the shadow vector until it hits the edge of the draw bounds
                        shadowArea.Add(lightDrawBounds.CastInternalRay(extrema[0], widthVector));
                        shadowArea.Add(lightDrawBounds.CastInternalRay(extrema[1], heightVector));

                        // Let's get the remaining verts that might exist to finish up the rect
                        List <Vector2> interiorVerts = lightDrawBounds.GetInteriorVertices(base.Position, widthVector, heightVector);
                        shadowArea.Add(interiorVerts);              // Add the interior verts (if any exist)

                        renderSystem.DirectScreenPaint(shadowArea); // Render the shadow
                        renderedShadow = true;                      // We just rendered a shadow; keep track of that
                    }

                    // Loop through all the objects between the last layer index and the current index
                    if (renderedShadow)
                    {
                        // Remove the shadows over the LAST shadow plane
                        for (int clearObjIndex = lastLayerDepthIndex; clearObjIndex < objectList.Count; clearObjIndex++)
                        {
                            this.ProcessSpriteDepthTransition(renderSystem, objectList[clearObjIndex]);
                        }

                        // Blur the shadow map if enabled
                        if (!float.IsPositiveInfinity(this.minShadowBlurDistance))
                        {
                            renderSystem.GraphicsDevice.SetRenderTarget(intermediateShadowMap); // We need to render to a temp target

                            // Configure the shader
                            this.shadowMapShader.ConfigureShader(renderSystem, 1);

                            // Set parameters
                            this.shadowMapShader.GetParameter("viewProjection").SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem));
                            this.shadowMapShader.GetParameter("cameraPosition").SetValue(renderSystem.GameCamera.PixelPosition);
                            this.shadowMapShader.GetParameter("lightPosition").SetValue(base.PixelPosition);
                            this.shadowMapShader.GetParameter("maxBlurDistance").SetValue(this.World.GetPixelFromWorld(this.maxShadowBlurDistance));
                            this.shadowMapShader.GetParameter("minBlurDistance").SetValue(this.World.GetPixelFromWorld(this.maxShadowBlurDistance));
                            this.shadowMapShader.GetParameter("shadowMap").SetValue(shadowMap);

                            this.shadowMapShader.ApplyPass(0);
                            renderSystem.DirectScreenPaint(lightDrawBounds);        // Render the shadow

                            renderSystem.GraphicsDevice.SetRenderTarget(shadowMap); // Set the shadow map for final render

                            // Update shadow map
                            this.shadowMapShader.GetParameter("shadowMap").SetValue(intermediateShadowMap);

                            this.shadowMapShader.ApplyPass(0);
                            renderSystem.DirectScreenPaint(lightDrawBounds); // Render
                        }
                    }
                }
            }

            renderSystem.SetRenderTargets(RenderTargetTypes.None, 0); // Resolve the render target
            renderSystem.RenderTargets.ReleaseTemporaryRenderTarget(intermediateShadowMap);
        }