/// <summary>
        /// This renders the refraction map;
        /// </summary>
        private void DrawRefractionMap(GraphicsDevice device, Camera camera, RenderSceneDelegate RenderScene)
        {
            // Clipping computations will be done after vertices have passed through the vertex shader and are in screen space. We must therefore represent the clipping planes
            // screen space as well, which is achieved by multiplying the plane coefficients by the view and projection matrices.

            Vector4 refractionPlaneCoefficients = new Vector4(0.0f, 1.0f, 0.0f, -waterHeight);
            refractionPlaneCoefficients = Vector4.Transform(refractionPlaneCoefficients, Matrix.Transpose(Matrix.Invert(camera.ViewMatrix * camera.ProjMatrix)));

            refractionClippingPlane = new Plane(refractionPlaneCoefficients);

            // Prepare the device for rendering to the desired render target

            device.ClipPlanes[0].Plane = refractionClippingPlane;
            device.ClipPlanes[0].IsEnabled = true;
            device.SetRenderTarget(0, refractionRenderTarget);
            device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);

            // Render the scene with clipping

            RenderScene();

            // Now disable the clipping plane and save the result to a texture

            device.ClipPlanes[0].IsEnabled = false;
            device.SetRenderTarget(0, null);
            refractionMap = refractionRenderTarget.GetTexture();
        }
        /// <summary>
        /// This draws the scene with reflective and refractive water. It takes a delegate function to perform the actual scene rendering needed to construct the refraction
        /// and reflection maps.
        /// </summary>
        /// <param name="camera"></param>
        public void Draw(Camera camera, RenderSceneDelegate RenderScene)
        {
            GraphicsDevice graphicsDevice = game.GraphicsDevice;

            // Render the refraction and reflection maps

            DrawRefractionMap(graphicsDevice, camera, RenderScene);
        }
        /// <summary>
        /// Loads graphics resources needed for the game.
        /// </summary>
        public override void LoadGraphicsContent(bool loadAllContent)
        {
            // Initialize the camera

            camera = new FirstPersonCamera(GameOptions.CameraAccelerationMagnitude, GameOptions.CameraRotationSpeed,
                                           GameOptions.CameraVelocityDecayRate);
            camera.AspectRatio = (float)ScreenManager.GraphicsDevice.Viewport.Width /
                                    (float)ScreenManager.GraphicsDevice.Viewport.Height;
            camera.Position = new Vector3(0, GameOptions.TerrainMaxHeight, 0);
            camera.Angles = new Vector3(-MathHelper.PiOver2, 0.0f, 0.0f);

            if (loadAllContent)
            {
                // Load the sky box
                skyBox = new SkyBox(ScreenManager.Game, ScreenManager.Content, camera);

                // Set up the terrain parameters
                TerrainQuadTreeParameters parameters = new TerrainQuadTreeParameters();

                parameters.HeightMapName = "Content\\Textures\\Heightmap";
                parameters.LayerMap0Name = "Content\\Textures\\grass01";
                parameters.LayerMap1Name = "Content\\Textures\\rock01";
                parameters.LayerMap2Name = "Content\\Textures\\snow01";
                parameters.GrassTextureName = "Content\\Textures\\grass";

                parameters.MaxHeight = GameOptions.TerrainMaxHeight;
                parameters.TerrainScale = GameOptions.TerrainScale;

                parameters.MaxScreenSpaceError = 0.075f;
                parameters.ScreenHeight = ScreenManager.Game.GraphicsDevice.Viewport.Height;
                parameters.FieldOfView = camera.FieldOfView;

                parameters.GrassChunkDimension = 30;
                parameters.GrassChunkStarSeparation = 266.6f;
                parameters.GrassStartFadingInDistance = 4000.0f;
                parameters.GrassStopFadingInDistance = 3900.0f;

                parameters.WindStrength = 100.0f;
                parameters.WindDirection = new Vector4(-1.0f, 0.0f, 0.0f, 0.0f);

                parameters.DoPreprocessing = true;

                parameters.ComputePerspectiveScalingFactor();

                terrain = new TerrainQuadTree(ScreenManager.Game, ScreenManager.Content, parameters);

                // Iniialize the water manager
                waterManager = new WaterManager(ScreenManager.Game, GameOptions.WaterHeight);
            }
        }
Exemple #4
0
        /// <summary>
        /// This loads the model and texture data needed to render the skybox.
        /// </summary>
        public SkyBox(Game game, ContentManager content, Camera camera)
        {
            this.game = game;
            this.camera = camera;

            GraphicsDevice graphicsDevice = game.GraphicsDevice;

            model = content.Load<Model>("Content\\Models\\Skybox");
            textures = new Texture2D[model.Meshes.Count];

            // Initialize the effect.

            effect = content.Load<Effect>("Content\\Shaders\\Skybox");

            // Save the textures in the mesh to the textures array.

            int textureCount = 0;

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect meshEffect in mesh.Effects)
                {
                    textures[textureCount] = meshEffect.Texture;
                    ++textureCount;
                }
            }

            // We need to pass our effect down to the child mesh parts.

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    part.Effect = effect.Clone(graphicsDevice);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// This renders the grass chunk.
        /// </summary>
        public void Draw(Vector3 center, Camera camera)
        {
            IGraphicsDeviceService igs = (IGraphicsDeviceService)game.Services.GetService(typeof(IGraphicsDeviceService));
            graphicsDevice = igs.GraphicsDevice;

            // Prepare the effect

            Matrix worldTransform = Matrix.CreateTranslation(center);

            quadTree.GrassShader.Parameters["world"].SetValue(worldTransform);
            quadTree.GrassShader.Parameters["view"].SetValue(camera.ViewMatrix);
            quadTree.GrassShader.Parameters["proj"].SetValue(camera.ProjMatrix);

            quadTree.GrassShader.Parameters["maxHeight"].SetValue(quadTree.Parameters.MaxHeight);
            quadTree.GrassShader.Parameters["textureSize"].SetValue(quadTree.HeightMap.Width);

            quadTree.GrassShader.Parameters["heightMap"].SetValue(quadTree.HeightMap);
            quadTree.GrassShader.Parameters["normalMap"].SetValue(quadTree.NormalMap);
            quadTree.GrassShader.Parameters["grassMap"].SetValue(quadTree.GrassTexture);

            quadTree.GrassShader.Parameters["terrainScale"].SetValue(quadTree.Parameters.TerrainScale);

            quadTree.GrassShader.Parameters["cameraPosition"].SetValue(camera.Position);

            quadTree.GrassShader.Parameters["timer"].SetValue(timer);

            quadTree.GrassShader.Parameters["startFadingInDistance"].SetValue(quadTree.Parameters.GrassStartFadingInDistance);
            quadTree.GrassShader.Parameters["stopFadingInDistance"].SetValue(quadTree.Parameters.GrassStopFadingInDistance);

            quadTree.GrassShader.Parameters["windStrength"].SetValue(quadTree.Parameters.WindStrength);
            quadTree.GrassShader.Parameters["windDirection"].SetValue(quadTree.Parameters.WindDirection);

            // Render it!

            int numVertices = dimension * dimension * 12;
            int numTriangles = dimension * dimension * 6;

            quadTree.GrassShader.CurrentTechnique = quadTree.GrassShader.Techniques["GrassDraw"];
            quadTree.GrassShader.Begin();

            graphicsDevice.VertexDeclaration = vertexDecl;
            graphicsDevice.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionNormalTexture.SizeInBytes);
            graphicsDevice.Indices = indexBuffer;

            foreach (EffectPass pass in quadTree.GrassShader.CurrentTechnique.Passes)
            {
                pass.Begin();

                graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numVertices, 0, numTriangles);

                pass.End();
            }

            quadTree.GrassShader.End();
        }
        /// <summary>
        /// This updates the chunk and its children if needed.
        /// </summary>
        public void Update(Camera camera)
        {
            float distance = (camera.Position - centerWorldPosition).Length();

            float screenSpaceError = geometricError / distance * quadTree.Parameters.PerspectiveScalingFactor;

            if (screenSpaceError > quadTree.Parameters.MaxScreenSpaceError && children.Count > 0)
            {
                splitIntoChildren = true;

                foreach (TerrainChunk child in children)
                {
                    child.Update(camera);
                }
            }
            else
            {
                splitIntoChildren = false;
            }
        }
        public void Render(Camera camera)
        {
            // If this node should be split, then render the four children instead

            if (splitIntoChildren)
            {
                foreach (TerrainChunk child in children)
                {
                    child.Render(camera);
                }
            }
            else
            {
                IGraphicsDeviceService igs = (IGraphicsDeviceService)quadTree.Game.Services.GetService(typeof(IGraphicsDeviceService));
                GraphicsDevice graphicsDevice = igs.GraphicsDevice;

                // Do frustum culling

                BoundingFrustum frustum = new BoundingFrustum(camera.ViewMatrix * camera.ProjMatrix);

                ContainmentType containment;
                frustum.Contains(ref boundingBox, out containment);

                if (containment == ContainmentType.Disjoint)
                    return;

                // Prepare the effect

                quadTree.TerrainShader.Parameters["world"].SetValue(worldTransform);
                quadTree.TerrainShader.Parameters["view"].SetValue(camera.ViewMatrix);
                quadTree.TerrainShader.Parameters["proj"].SetValue(camera.ProjMatrix);

                quadTree.TerrainShader.Parameters["maxHeight"].SetValue(quadTree.Parameters.MaxHeight);
                quadTree.TerrainShader.Parameters["textureSize"].SetValue(quadTree.HeightMap.Width);

                quadTree.TerrainShader.Parameters["heightMap"].SetValue(quadTree.HeightMap);
                quadTree.TerrainShader.Parameters["grassMap"].SetValue(quadTree.LayerMap0);
                quadTree.TerrainShader.Parameters["rockMap"].SetValue(quadTree.LayerMap1);
                quadTree.TerrainShader.Parameters["snowMap"].SetValue(quadTree.LayerMap2);
                quadTree.TerrainShader.Parameters["normalMap"].SetValue(quadTree.NormalMap);

                quadTree.TerrainShader.Parameters["uStart"].SetValue(textureCoordinates.UStart);
                quadTree.TerrainShader.Parameters["uEnd"].SetValue(textureCoordinates.UEnd);
                quadTree.TerrainShader.Parameters["vStart"].SetValue(textureCoordinates.VStart);
                quadTree.TerrainShader.Parameters["vEnd"].SetValue(textureCoordinates.VEnd);

                // Render it!

                quadTree.TerrainShader.CurrentTechnique = quadTree.TerrainShader.Techniques["TerrainDraw"];
                quadTree.TerrainShader.Begin();

                foreach (EffectPass pass in quadTree.TerrainShader.CurrentTechnique.Passes)
                {
                    pass.Begin();

                    quadTree.CommonGrid.Draw();

                    pass.End();
                }

                quadTree.TerrainShader.End();
            }
        }
        /// <summary>
        /// Renders the grass chunks distributed across the terrain.
        /// </summary>
        /// <param name="camera"></param>
        private void RenderGrass(Camera camera)
        {
            BoundingFrustum frustum = new BoundingFrustum(camera.ViewMatrix * camera.ProjMatrix);

            float grassChunkSize = grassChunk.Dimension * grassChunk.StarSeparation;

            foreach (Vector3 position in grassChunkPositions)
            {
                // Do frustum culling.

                Vector2 cameraPosVec2 = new Vector2(camera.Position.X, camera.Position.Z);
                Vector2 grassPosVec2 = new Vector2(position.X, position.Z);

                if ((cameraPosVec2 - grassPosVec2).Length() > parameters.GrassStartFadingInDistance + grassChunkSize / 2.0f)
                    continue;

                BoundingBox boundingBox = new BoundingBox(new Vector3(position.X - grassChunkSize / 2.0f, 0.0f, position.Z - grassChunkSize / 2.0f),
                                              new Vector3(position.X + grassChunkSize / 2.0f, parameters.MaxHeight + grassChunk.QuadHeight, position.Z + grassChunkSize / 2.0f));

                ContainmentType containment;
                frustum.Contains(ref boundingBox, out containment);

                if (containment == ContainmentType.Disjoint)
                    continue;

                grassChunk.Draw(position, camera);
            }
        }
        /// <summary>
        /// This draws the terrain using the GPU for height map displacement and texture blending.
        /// </summary>
        public void Draw(Camera camera)
        {
            GraphicsDevice graphicsDevice = game.GraphicsDevice;

            graphicsDevice.RenderState.CullMode = CullMode.None;
            //graphicsDevice.RenderState.FillMode = FillMode.WireFrame;

            rootNode.Update(camera);
            rootNode.Render(camera);

            RenderGrass(camera);

            graphicsDevice.RenderState.AlphaBlendEnable = false;
            graphicsDevice.RenderState.AlphaTestEnable = false;
            graphicsDevice.RenderState.DepthBufferWriteEnable = true;
        }