示例#1
0
 private void RenderOverlays()
 {
     PIXHelper.BeginEvent("Render overlays");
     foreach (Renderable renderable in overlays)
     {
         Debug.Assert(renderable.RenderMode == RenderMode.RenderOverlays);
         renderable.Draw(this);
     }
     PIXHelper.EndEvent();
 }
示例#2
0
        private void RenderParticles()
        {
            //transparentRenderables.Sort(TransparentRenderableComparison);
            PIXHelper.BeginEvent("Render particles");

            foreach (Renderable renderable in transparentRenderables)
            {
                Debug.Assert(renderable.RenderMode == RenderMode.RenderToSceneAlpha);
                renderable.Draw(this);
            }

            PIXHelper.BeginEvent("Render lava fires");
            if (explosionSystem != null)
            {
                explosionSystem.Render(lastFrameTime, currentFrameTime);
            }
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Render Snow");
            if (snowSystem != null)
            {
                snowSystem.Render(lastFrameTime, currentFrameTime);
            }
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Render ice explosion");
            if (iceExplosionSystem != null)
            {
                iceExplosionSystem.Render(Time.PausableLast / 1000d, Time.PausableAt / 1000d);
            }
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Render robot explosion");
            if (fireExplosionSystem != null)
            {
                fireExplosionSystem.Render(Time.PausableLast / 1000d, Time.PausableAt / 1000d);
            }
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Render flamethrower");
            if (flamethrowerSystem != null)
            {
                flamethrowerSystem.Render(Time.PausableLast / 1000d, Time.PausableAt / 1000d);
            }
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Render ice spike");
            if (iceSpikeSystem != null)
            {
                iceSpikeSystem.Render(Time.PausableLast / 1000d, Time.PausableAt / 1000d);
            }
            PIXHelper.EndEvent();

            PIXHelper.EndEvent();
        }
示例#3
0
        /// <summary>
        /// If regular foward rendering is being used for transparents, this method is called
        /// and renders the transparents
        /// </summary>
        private void DrawTransparents()
        {
            PIXHelper.BeginEvent("Draw Transparents Pass");

            List <Vector3> lightPositions = new List <Vector3>();
            List <float>   lightRanges    = new List <float>();
            List <Vector3> lightColors    = new List <Vector3>();

            foreach (Light light in lights)
            {
                if (light is PointLight)
                {
                    PointLight pointLight = (PointLight)light;
                    lightPositions.Add(Vector3.Transform(pointLight.Position, camera.ViewMatrix));
                    lightRanges.Add(pointLight.Range);
                    lightColors.Add(pointLight.Color);
                }
                else if (light is DirectionalLight)
                {
                    DirectionalLight directionalLight = (DirectionalLight)light;

                    Vector3 lightDirVS = Vector3.TransformNormal(directionalLight.Direction, camera.ViewMatrix);
                    transparentEffect.Parameters["LightDirVS"].SetValue(Vector3.Normalize(lightDirVS));
                    transparentEffect.Parameters["LightColor"].SetValue(light.Color);
                }
            }

            transparentEffect.Parameters["LightPositionsVS"].SetValue(lightPositions.ToArray());
            transparentEffect.Parameters["LightRanges"].SetValue(lightRanges.ToArray());
            transparentEffect.Parameters["LightColors"].SetValue(lightColors.ToArray());
            transparentEffect.Parameters["AmbientColor"].SetValue(AmbientLight);
            transparentEffect.Parameters["EnablePointLights"].SetValue(enablePointLights);
            transparentEffect.Parameters["ViewToLight"].SetValue(camera.WorldMatrix * lightCam.ViewProjectionMatrix);
            transparentEffect.Parameters["ShadowMapTexture"].SetValue(shadowMap.GetTexture());
            transparentEffect.Parameters["ShadowMapDimensions"].SetValue(new Vector2((int)shadowMapSize));

            if (enableNormalMaps)
            {
                transparentEffect.CurrentTechnique = transparentEffect.Techniques["TransparentNM"];
            }
            else
            {
                transparentEffect.CurrentTechnique = transparentEffect.Techniques["Transparent"];
            }

            foreach (ModelInstance instance in sortedTransparents)
            {
                instance.Draw(GraphicsDevice, transparentEffect, camera);
            }

            PIXHelper.EndEvent();
        }
示例#4
0
        /// <summary>
        /// Draws all opaque instances to the shadow map
        /// </summary>
        private void DrawShadowMap()
        {
            PIXHelper.BeginEvent("Draw ShadowMap");

            GraphicsDevice.SetRenderTarget(0, shadowMap);
            GraphicsDevice.DepthStencilBuffer = shadowMapDS;
            GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer | ClearOptions.Stencil, Vector4.One, 1.0f, 0);
            foreach (ModelInstance instance in opaques)
            {
                instance.Draw(GraphicsDevice, shadowMapEffect, lightCam);
            }

            PIXHelper.EndEvent();
        }
示例#5
0
        private void DrawScreen()
        {
            PIXHelper.BeginEvent("Drawing Results to Screen");

            GraphicsDevice.SetRenderTarget(0, null);
            GraphicsDevice.DepthStencilBuffer = nonMSAADS;
            GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer | ClearOptions.Stencil, Vector4.Zero, 1.0f, 0);

            spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
            spriteEffect.Begin(SaveStateMode.None);
            spriteEffect.CurrentTechnique.Passes[0].Begin();
            spriteBatch.Draw(colorBuffer.GetTexture(), Vector2.Zero, Color.White);
            spriteBatch.End();
            spriteEffect.CurrentTechnique.Passes[0].End();
            spriteEffect.End();
        }
示例#6
0
        private void RenderScene()
        {
            PIXHelper.BeginEvent("Render Scene");

            if (EnablePostProcessing)
            {
                Device.SetRenderTargets(targetOpaqueColorBuffer, targetOpaqueRenderChannels, targetOpaqueDepth);
            }

            // clear the render targets
            Device.Clear(Color.White);

            // make sure to disable blending. XNA does not like alpha blending on floating point surfaces. And
            // it looks like it does not set them correctly when specified in .fx files. just disable it to make sure
            // that everything works as it should!
            Device.BlendState = BlendState.Opaque;

            foreach (Renderable renderable in opaqueRenderables)
            {
                Debug.Assert(renderable.RenderMode == RenderMode.RenderToScene);
                renderable.Draw(this);
            }

            if (EnablePostProcessing)
            {
                Device.SetRenderTargets(null);
            }

            //Texture2D texture = TargetDepth.GetTexture();
            //float[] pixelData = new float[texture.Width * texture.Height];
            //texture.GetData(pixelData, 0, texture.Width * texture.Height);
            //Console.WriteLine("start");
            //for (int i = 0; i < texture.Width * texture.Height; i++)
            //    if (pixelData[i] != 0.0f)
            //    {
            //        float g = pixelData[i];
            //        Console.WriteLine(g);
            //    }
            //Console.WriteLine("end");
            //int a = 0;

            PIXHelper.EndEvent();
        }
示例#7
0
        public void Render(
            Texture2D hdrColorBuffer, Texture2D renderChannelBuffer,
            RenderTarget2D targetIntermediateBlurredHDRColorBuffer, RenderTarget2D targetIntermediateBlurredRenderChannelBuffer,
            RenderTarget2D targetBlurredHDRColorBuffer, RenderTarget2D targetBlurredRenderChannelBuffer
            )
        {
            // pass 1 horizontal blur
            PIXHelper.BeginEvent("Horizontal Blur");
            SetBlurEffectParameters(
                1.0f / hdrColorBuffer.Width,
                0,
                hdrColorBuffer,
                renderChannelBuffer
                );
            DrawFullscreenQuad(
                hdrColorBuffer,
                targetIntermediateBlurredHDRColorBuffer, targetIntermediateBlurredRenderChannelBuffer,
                gaussianBlurEffect
                );
            PIXHelper.EndEvent();

            // result
            Texture2D intermediateBlurredHDRColorBuffer      = targetIntermediateBlurredHDRColorBuffer;
            Texture2D intermediateBlurredRenderChannelBuffer = targetIntermediateBlurredRenderChannelBuffer;

            // pass 2 vertical blurr
            PIXHelper.BeginEvent("Vertical Blur");
            SetBlurEffectParameters(
                0,
                1.0f / hdrColorBuffer.Height,
                intermediateBlurredHDRColorBuffer,
                intermediateBlurredRenderChannelBuffer
                );
            DrawFullscreenQuad(
                intermediateBlurredHDRColorBuffer,
                targetBlurredHDRColorBuffer, targetBlurredRenderChannelBuffer,
                gaussianBlurEffect
                );
            PIXHelper.EndEvent();
        }
示例#8
0
        private void UpdateParticles(
            double currentFrameTime,
            int nextTexture
            )
        {
            PIXHelper.BeginEvent("Update particles");

            particleUpdateEffect.Parameters["View"].SetValue(renderer.Camera.View);
            particleUpdateEffect.Parameters["Projection"].SetValue(renderer.Camera.Projection);
            particleUpdateEffect.Parameters["StartSize"].SetValue(new Vector2(5.0f, 10.0f));
            particleUpdateEffect.Parameters["EndSize"].SetValue(new Vector2(50.0f, 200.0f));
            particleUpdateEffect.Parameters["MinColor"].SetValue(Vector4.One);
            particleUpdateEffect.Parameters["MaxColor"].SetValue(Vector4.One);
            particleUpdateEffect.Parameters["ViewportHeight"].SetValue(device.Viewport.Height);
            particleUpdateEffect.Parameters["ViewportWidth"].SetValue(device.Viewport.Width);
            particleUpdateEffect.Parameters["Time"].SetValue((float)currentFrameTime);
            particleUpdateEffect.Parameters["Dt"].SetValue((float)SimulationStep);
            particleUpdateEffect.Parameters["PositionTexture"].SetValue(positionTextures[activeTexture]);
            particleUpdateEffect.Parameters["VelocityTexture"].SetValue(velocityTextures[activeTexture]);
            particleUpdateEffect.Parameters["RandomTexture"].SetValue(renderer.VectorCloudTexture);
            particleUpdateEffect.Parameters["SpriteTexture"].SetValue(spriteTexture);
            if (particleUpdateEffect.Parameters["ViewportSize"] != null)
            {
                particleUpdateEffect.Parameters["ViewportSize"].SetValue(new Vector2(positionTextures[nextTexture].Width, positionTextures[nextTexture].Height));
            }
            SetUpdateParameters(particleUpdateEffect.Parameters);

            Texture2D positionTexture = positionTextures[activeTexture];

            // TODO: fix rendering code!
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, null, null, particleUpdateEffect);

            spriteBatch.Draw(positionTexture, new Rectangle(0, 0, positionTexture.Width, positionTexture.Height), Color.White);

            spriteBatch.End();

            PIXHelper.EndEvent();
        }
示例#9
0
        public void Render()
        {
            PIXHelper.BeginEvent("Render Frame");

            renderTime.Update();
            //Console.WriteLine("rendering {0}", renderTime.PausableAt);

            Game.Instance.Profiler.BeginSection("beginning_stuff");
            Update();
            LightManager.Update(this);

            device.Clear(Color.White);

            // 1) Set the light's render target
            device.SetRenderTargets(lightRenderTarget);
            Game.Instance.Profiler.EndSection("beginning_stuff");

            Game.Instance.Profiler.BeginSection("rendering");

            // 2) Render the scene from the perspective of the light
            Game.Instance.Profiler.BeginSection("renderer_shadow");
            RenderShadow();
            Game.Instance.Profiler.EndSection("renderer_shadow");

            // 3) Set our render target back to the screen, and get the
            //depth texture created by step 2
            Game.Instance.Profiler.BeginSection("change_render_target");
            device.SetRenderTargets(null);
            lightResolve = lightRenderTarget;
            Game.Instance.Profiler.EndSection("change_render_target");

            // 4) Render the scene from the view of the camera,
            //and do depth comparisons in the shader to determine shadowing
            Game.Instance.Profiler.BeginSection("renderer_scene");
            RenderScene();
            Game.Instance.Profiler.EndSection("renderer_scene");

            // TODO: alpha blended objects...
            bool hasAlphaObjects = false;// transparentRenderablesTEST.Count > 0;

            Game.Instance.Profiler.BeginSection("render_scene_alpha");
            if (hasAlphaObjects)
            {
                RenderSceneAlpha();
            }
            Game.Instance.Profiler.EndSection("render_scene_alpha");

            if (EnablePostProcessing)
            {
                Game.Instance.Profiler.BeginSection("postprocessing");
                PIXHelper.BeginEvent("PostProcessing");

                // downscaling is done as part of the blur during the glow-pass
                if (hasAlphaObjects)
                {
                    Game.Instance.Profiler.BeginSection("combine");
                    combinePass.Render(targetOpaqueColorBuffer, targetAlphaColorBuffer, targetHDRColorBuffer);
                    combinePass.Render(targetOpaqueRenderChannels, targetAlphaRenderChannels, targetRenderChannels);
                    combineDepthPass.Render(targetOpaqueDepth, targetAlphaDepth, targetDepth);
                    Game.Instance.Profiler.EndSection("combine");

                    Game.Instance.Profiler.BeginSection("renderer_post_glow");
                    glowPass.Render(
                        targetHDRColorBuffer, targetRenderChannels,
                        targetHorizontalBlurredHDRColorBuffer, targetHorizontalBlurredRenderChannels,
                        targetBlurredHDRColorBuffer, targetBlurredRenderChannels
                        );
                    Game.Instance.Profiler.EndSection("renderer_post_glow");

                    // FIXME: do we really need to downscale and blur the renderchannels? we don't use
                    // the blurred version.

                    Game.Instance.Profiler.BeginSection("renderer_post_hdr");
                    hdrCombinePass.Render(
                        targetHDRColorBuffer, targetBlurredHDRColorBuffer, targetRenderChannels,
                        targetDepth
                        );
                    Game.Instance.Profiler.EndSection("renderer_post_hdr");
                }
                else
                {
                    Game.Instance.Profiler.BeginSection("renderer_post_glow");
                    PIXHelper.BeginEvent("Glow Pass");
                    glowPass.Render(
                        targetOpaqueColorBuffer, targetOpaqueRenderChannels,
                        targetHorizontalBlurredHDRColorBuffer, targetHorizontalBlurredRenderChannels,
                        targetBlurredHDRColorBuffer, targetBlurredRenderChannels
                        );
                    PIXHelper.EndEvent();
                    Game.Instance.Profiler.EndSection("renderer_post_glow");

                    // FIXME: do we really need to downscale and blur the renderchannels? we don't use
                    // the blurred version.

                    Game.Instance.Profiler.BeginSection("renderer_post_hdr");
                    PIXHelper.BeginEvent("HDR Combine Pass");
                    hdrCombinePass.Render(
                        targetOpaqueColorBuffer, targetBlurredHDRColorBuffer, targetOpaqueRenderChannels,
                        targetOpaqueDepth
                        );
                    PIXHelper.EndEvent();
                    Game.Instance.Profiler.EndSection("renderer_post_hdr");
                }

                PIXHelper.EndEvent();
                Game.Instance.Profiler.EndSection("postprocessing");
            }

            RenderParticles();
            RenderSceneAfterPost();

            Game.Instance.Profiler.EndSection("rendering");

            // 6) Render overlays
            Game.Instance.Profiler.BeginSection("overlay");
            RenderOverlays();
            Game.Instance.Profiler.EndSection("overlay");

            PIXHelper.EndEvent();
        }
示例#10
0
        private void Update()
        {
            if (Camera != null)
            {
                // should only be called if a level has already been loaded
                Camera.Update(this);
                Camera.RecomputeFrame(ref opaqueRenderables);
            }

            RendererUpdateQueue q = GetNextUpdateQueue();

            while (q != null)
            {
                for (int i = 0; i < q.Count; ++i)
                {
                    q[i].Apply(q.Timestamp);
                }

                q = GetNextUpdateQueue();
            }

            foreach (Renderable renderable in updateRenderables)
            {
                renderable.Update(this);
            }

            Game.Instance.Profiler.BeginSection("particle_systems");
            PIXHelper.BeginEvent("Update Particles");

            PIXHelper.BeginEvent("Update lava flames");
            Game.Instance.Profiler.BeginSection("explosion_system");
            if (explosionSystem != null)
            {
                explosionSystem.Update(Time.Last / 1000d, Time.At / 1000d);
            }
            Game.Instance.Profiler.EndSection("explosion_system");
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Update snow");
            Game.Instance.Profiler.BeginSection("snow_system");
            if (snowSystem != null)
            {
                snowSystem.Update(Time.Last / 1000d, Time.At / 1000d);
            }
            Game.Instance.Profiler.EndSection("snow_system");
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Update ice explosions");
            Game.Instance.Profiler.BeginSection("ice_explosion_system");
            if (iceExplosionSystem != null)
            {
                iceExplosionSystem.Update(Time.PausableLast / 1000d, Time.PausableAt / 1000d);
            }
            Game.Instance.Profiler.EndSection("ice_explosion_system");
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Update fire explosions");
            Game.Instance.Profiler.BeginSection("fire_explosion_system");
            if (fireExplosionSystem != null)
            {
                fireExplosionSystem.Update(Time.PausableLast / 1000d, Time.PausableAt / 1000d);
            }
            Game.Instance.Profiler.EndSection("fire_explosion_system");
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Update flamethrowers");
            Game.Instance.Profiler.BeginSection("flamethrower_system");
            if (flamethrowerSystem != null)
            {
                flamethrowerSystem.Update(Time.PausableLast / 1000d, Time.PausableAt / 1000d);
            }
            Game.Instance.Profiler.EndSection("flamethrower_system");
            PIXHelper.EndEvent();

            PIXHelper.BeginEvent("Update ice spikes");
            Game.Instance.Profiler.BeginSection("ice_spike_system");
            if (iceSpikeSystem != null)
            {
                iceSpikeSystem.Update(Time.PausableLast / 1000d, Time.PausableAt / 1000d);
            }
            Game.Instance.Profiler.EndSection("ice_spike_system");
            PIXHelper.EndEvent();

            PIXHelper.EndEvent();
            Game.Instance.Profiler.EndSection("particle_systems");
        }
示例#11
0
        /// <summary>
        /// Renders the composite pass, where instances a re-rendered and sample the
        /// L-Buffer to determine the lighting value that should be applied.
        /// </summary>
        private void DrawCompositePass()
        {
            PIXHelper.BeginEvent("Draw Composite Pass");

            GraphicsDevice.SetRenderTarget(0, colorBuffer);
            GraphicsDevice.DepthStencilBuffer = msaaDS;
            GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer | ClearOptions.Stencil,
                                 Color.Black, 1.0f, 0);

            compositeEffect.Parameters["GBufferDimensions"].SetValue(gBufferDimensions);
            compositeEffect.Parameters["RTDimensions"].SetValue(new Vector2(ScreenWidth, ScreenHeight));
            compositeEffect.Parameters["AmbientColor"].SetValue(AmbientLight);
            compositeEffect.Parameters["LightTexture"].SetValue(lightBuffer.GetTexture());
            compositeEffect.Parameters["DepthIDTexture"].SetValue(depthIDBuffer.GetTexture());
            compositeEffect.Parameters["Alpha"].SetValue(1.0f);

            PIXHelper.BeginEvent("Opaques");

            // Draw the opaques
            if (gBufferSize == GBufferSize.FullSize && transparencyMode == TransparencyMode.ForwardRendered)
            {
                compositeEffect.CurrentTechnique = compositeEffect.Techniques["CompositeOpaque"];
            }
            else
            {
                compositeEffect.CurrentTechnique = compositeEffect.Techniques["CompositeOpaqueFiltered"];
            }

            int instanceID = 1;

            foreach (ModelInstance instance in opaques)
            {
                compositeEffect.Parameters["InstanceID"].SetValue(instanceID);
                instance.Draw(GraphicsDevice, compositeEffect, camera);
                ++instanceID;
            }

            PIXHelper.EndEvent();

            if (transparencyMode == TransparencyMode.ForwardRendered)
            {
                PIXHelper.EndEvent();
                return;
            }

            PIXHelper.BeginEvent("Transparents");

            compositeEffect.CurrentTechnique = compositeEffect.Techniques["CompositeTransparent"];
            compositeEffect.Parameters["Alpha"].SetValue(0.5f);
            foreach (ModelInstance instance in sortedTransparents)
            {
                compositeEffect.Parameters["InstanceID"].SetValue(instanceID);
                compositeEffect.Parameters["XFilterOffsets"].SetValue(XFilterOffsets[instanceID % NumMasks]);
                compositeEffect.Parameters["YFilterOffsets"].SetValue(YFilterOffsets[instanceID % NumMasks]);
                instance.Draw(GraphicsDevice, compositeEffect, camera);
                ++instanceID;
            }

            PIXHelper.EndEvent();

            PIXHelper.EndEvent();
        }
示例#12
0
        /// <summary>
        /// Renders the lighting pass by rendering all lights to the L-Buffer
        /// </summary>
        private void DrawLights()
        {
            PIXHelper.BeginEvent("Draw Lights");

            GraphicsDevice.SetRenderTarget(0, lightBuffer);
            GraphicsDevice.SetRenderTarget(1, null);
            GraphicsDevice.Clear(ClearOptions.Target, Vector4.Zero, 1.0f, 0);

            lightEffect.Parameters["FarClip"].SetValue(camera.FarClip);
            lightEffect.Parameters["GBufferDimensions"].SetValue(gBufferDimensions);
            lightEffect.Parameters["DepthIDTexture"].SetValue(depthIDBuffer.GetTexture());
            lightEffect.Parameters["NormalSpecTexture"].SetValue(normalSpecularBuffer.GetTexture());

            foreach (Light light in lights)
            {
                lightEffect.Parameters["LightColor"].SetValue(light.Color);

                if (light is PointLight && enablePointLights)
                {
                    PointLight pointLight = (PointLight)light;

                    Matrix worldMatrix = Matrix.CreateScale(pointLight.Range) * Matrix.CreateTranslation(pointLight.Position);
                    lightEffect.Parameters["WorldView"].SetValue(worldMatrix * camera.ViewMatrix);
                    lightEffect.Parameters["WorldViewProjection"].SetValue(worldMatrix * camera.ViewProjectionMatrix);
                    lightEffect.Parameters["LightRange"].SetValue(pointLight.Range);
                    lightEffect.Parameters["LightPosVS"].SetValue(Vector3.Transform(pointLight.Position, camera.ViewMatrix));

                    // For our light volume we'll want to render front faces if the volume intersects
                    // our far clipping plane, or back faces otherwise.
                    float lightDepth = -Vector3.Transform(pointLight.Position, camera.ViewMatrix).Z;
                    if (lightDepth > camera.FarClip - pointLight.Range)
                    {
                        lightEffect.CurrentTechnique = lightEffect.Techniques["PointLightFront"];
                    }
                    else
                    {
                        lightEffect.CurrentTechnique = lightEffect.Techniques["PointLightBack"];
                    }

                    lightEffect.Begin(SaveStateMode.None);
                    lightEffect.CurrentTechnique.Passes[0].Begin();

                    ModelMesh     mesh     = lightSphere.Meshes[0];
                    ModelMeshPart meshPart = mesh.MeshParts[0];

                    GraphicsDevice.Indices           = mesh.IndexBuffer;
                    GraphicsDevice.VertexDeclaration = meshPart.VertexDeclaration;
                    GraphicsDevice.Vertices[0].SetSource(mesh.VertexBuffer, meshPart.StreamOffset, meshPart.VertexStride);

                    GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                                                         meshPart.BaseVertex,
                                                         0,
                                                         meshPart.NumVertices,
                                                         meshPart.StartIndex,
                                                         meshPart.PrimitiveCount);

                    lightEffect.CurrentTechnique.Passes[0].End();
                    lightEffect.End();
                }
                else if (light is DirectionalLight)
                {
                    DirectionalLight directionalLight = (DirectionalLight)light;

                    // Do shadow mapping first
                    DrawShadowMap();

                    // Now draw the directional light
                    GraphicsDevice.SetRenderTarget(0, lightBuffer);
                    GraphicsDevice.DepthStencilBuffer = nonMSAADS;
                    lightEffect.Parameters["ShadowMapTexture"].SetValue(shadowMap.GetTexture());
                    lightEffect.Parameters["ViewToLight"].SetValue(camera.WorldMatrix * lightCam.ViewProjectionMatrix);
                    lightEffect.Parameters["ShadowMapDimensions"].SetValue(new Vector2((int)shadowMapSize));

                    Vector3 lightDirVS = Vector3.TransformNormal(directionalLight.Direction, camera.ViewMatrix);
                    lightEffect.Parameters["LightDirVS"].SetValue(Vector3.Normalize(lightDirVS));

                    // Get the frustum corners for position reconstruction
                    Vector3[] cornersWS = camera.BoundingFrustum.GetCorners();
                    Vector3[] cornersVS = new Vector3[4];
                    for (int i = 0; i < 4; ++i)
                    {
                        cornersVS[i] = Vector3.Transform(cornersWS[i + 4], camera.ViewMatrix);
                    }
                    lightEffect.Parameters["FrustumCornersVS"].SetValue(cornersVS);

                    lightEffect.CurrentTechnique = lightEffect.Techniques["DirectionalLight"];

                    lightEffect.Begin(SaveStateMode.None);
                    lightEffect.CurrentTechnique.Passes[0].Begin();

                    quad.Draw(GraphicsDevice);

                    lightEffect.CurrentTechnique.Passes[0].End();
                    lightEffect.End();
                }
            }

            PIXHelper.EndEvent();
        }
示例#13
0
        /// <summary>
        /// Draws all opaque instances to the G-Buffer, as well as transparents (if deferred mode
        /// is being used to render the transparents)
        /// </summary>
        private void DrawGBuffer()
        {
            PIXHelper.BeginEvent("Draw G-Buffer");

            GraphicsDevice.SetRenderTarget(0, depthIDBuffer);
            GraphicsDevice.SetRenderTarget(1, normalSpecularBuffer);
            GraphicsDevice.DepthStencilBuffer = nonMSAADS;
            GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Stencil | ClearOptions.Target, Vector4.Zero, 1.0f, 0);

            PIXHelper.BeginEvent("Opaques");

            if (enableNormalMaps)
            {
                gBufferEffect.CurrentTechnique = gBufferEffect.Techniques["GBufferNM"];
            }
            else
            {
                gBufferEffect.CurrentTechnique = gBufferEffect.Techniques["GBuffer"];
            }

            // We'll make sure each instance has a unique ID by incrementing a variable
            // every time we render one.  0 is reserved for no instances, so we start
            // at one.
            int instanceID = 1;

            foreach (ModelInstance instance in opaques)
            {
                gBufferEffect.Parameters["InstanceID"].SetValue(instanceID);
                instance.Draw(GraphicsDevice, gBufferEffect, camera);
                ++instanceID;
            }

            PIXHelper.EndEvent();

            if (transparencyMode == TransparencyMode.ForwardRendered)
            {
                PIXHelper.EndEvent();
                return;
            }

            PIXHelper.BeginEvent("Transparents");

            if (enableNormalMaps)
            {
                gBufferEffect.CurrentTechnique = gBufferEffect.Techniques["GBufferMaskNM"];
            }
            else
            {
                gBufferEffect.CurrentTechnique = gBufferEffect.Techniques["GBufferMask"];
            }

            foreach (ModelInstance instance in sortedTransparents)
            {
                // For each instance, rotate through our 3 output masks
                gBufferEffect.Parameters["OutputMask"].SetValue(OutputMasks[instanceID % NumMasks]);
                gBufferEffect.Parameters["InstanceID"].SetValue(instanceID);
                instance.Draw(GraphicsDevice, gBufferEffect, camera);
                ++instanceID;
            }


            PIXHelper.EndEvent();

            PIXHelper.EndEvent();
        }
示例#14
0
        private void CreateParticles(
            double lastFrameTime,
            double currentFrameTime,
            double dt
            )
        {
            Game.Instance.Profiler.BeginSection("create_particles");
            PIXHelper.BeginEvent("Create particles");

            Game.Instance.Profiler.BeginSection("count");
            Vector2 positionHalfPixel = new Vector2(1.0f / (2.0f * positionTextures[0].Width), 1.0f / (2.0f * positionTextures[0].Height));

            Vector2 positionPixel = new Vector2(1.0f / (positionTextures[0].Width), 1.0f / (positionTextures[0].Height));

            int[] particleCount = new int[emitters.Count];

            int sumParticleCount = 0;

            for (int emitterIndex = 0; emitterIndex < emitters.Count; ++emitterIndex)
            {
                ParticleEmitter emitter = emitters[emitterIndex];
                particleCount[emitterIndex] = emitter.CalculateParticleCount(lastFrameTime, currentFrameTime);
                sumParticleCount           += particleCount[emitterIndex];
            }
            Game.Instance.Profiler.EndSection("count");

            // nothing to do if there are no new particles!
            if (sumParticleCount == 0)
            {
                PIXHelper.EndEvent();
                Game.Instance.Profiler.EndSection("create_particles");
                return;
            }

            Game.Instance.Profiler.BeginSection("allocate");
            CreateVertexArray vertices = renderer.StatefulParticleResourceManager.AllocateCreateVertexArray(sumParticleCount * 3);

            Game.Instance.Profiler.EndSection("allocate");

            Game.Instance.Profiler.BeginSection("create");
            int maxindex = positionTextures[0].Width * positionTextures[0].Height;

            for (int i = 0; i < sumParticleCount; ++i)
            {
                if (nextParticleIndex >= maxindex)
                {
                    nextParticleIndex = 0;
                }

                int textureSize = textureSizes[(int)GetSystemSize()];
                int x           = nextParticleIndex % textureSize;
                int y           = nextParticleIndex / textureSize;

                Debug.Assert(textureSize == positionTextures[0].Width);
                Debug.Assert(textureSize == positionTextures[0].Height);

                Vector2[] offsets =
                {
                    new Vector2(-1, -1),
                    new Vector2(1,  -1),
                    new Vector2(0, 1)
                };

                for (int j = 0; j < 3; ++j)
                {
                    vertices.Array[i * 3 + j] = new CreateVertex(
                        Vector3.Zero,
                        Vector3.Zero,
                        new Vector2(
                            -1.0f + positionPixel.X + 2.0f * x * positionPixel.X + 2 * offsets[j].X * positionPixel.X,
                            -1.0f + positionPixel.Y + 2.0f * y * positionPixel.Y + 2 * offsets[j].Y * positionPixel.Y
                            ),
                        new Short2(
                            x,
                            y
                            ),
                        0 // emitterIndex
                        );
                }

                ++nextParticleIndex;
            }
            Game.Instance.Profiler.EndSection("create");

            Game.Instance.Profiler.BeginSection("emit");
            int vertexIndex = 0;

            for (int emitterIndex = 0; emitterIndex < emitters.Count; ++emitterIndex)
            {
                ParticleEmitter emitter = emitters[emitterIndex];

                emitter.CreateParticles(lastFrameTime, currentFrameTime, vertices.Array, vertexIndex, particleCount[emitterIndex]);
                vertexIndex += particleCount[emitterIndex];
            }
            Game.Instance.Profiler.EndSection("emit");

            Game.Instance.Profiler.BeginSection("render");
            int localCreateVerticesIndex = 0;

            int verticesCopied = 0;

            while (verticesCopied < vertices.OccupiedSize)
            {
                int passVerticesCount     = vertices.OccupiedSize - verticesCopied;
                int passVerticesAvailable = createVertexBufferSize - localCreateVerticesIndex;
                if (passVerticesCount > passVerticesAvailable)
                {
                    passVerticesCount = passVerticesAvailable;
                }

                for (int j = 0; j < passVerticesCount; ++j)
                {
                    localCreateVertices[localCreateVerticesIndex + j] = vertices.Array[verticesCopied + j];
                }

                verticesCopied           += passVerticesCount;
                localCreateVerticesIndex += passVerticesCount;

                if (localCreateVerticesIndex >= createVertexBufferSize - createVertexBufferIndex)
                {
                    FlushCreateParticles(verticesCopied, currentFrameTime, dt);
                    localCreateVerticesIndex = 0;
                    createVertexBufferIndex  = 0;
                }
            }

            renderer.StatefulParticleResourceManager.FreeCreateVertexArray(vertices);

            if (localCreateVerticesIndex > 0)
            {
                FlushCreateParticles(localCreateVerticesIndex, currentFrameTime, dt);
            }

            Game.Instance.Profiler.EndSection("render");

            PIXHelper.EndEvent();
            Game.Instance.Profiler.EndSection("create_particles");
        }