protected override void Initialise() { Resource.EnableResourceTracking(); Camera3D camera = new Camera3D(); camera.LookAt(Vector3.Zero, new Vector3(0, 0, 5), Vector3.UnitY); //create the draw target. drawToScreen = new DrawTargetScreen(this, camera); drawToScreen.ClearBuffer.ClearColour = Color.CornflowerBlue; //create a shader to display the geometry (this is the same as tutorial 02) Vector3 lightDirection = new Vector3(1.0f, 0.5f, 0.5f); MaterialShader material = new MaterialShader(new MaterialLightCollection()); material.UsePerPixelSpecular = true; material.Lights.AmbientLightColour = Color.CornflowerBlue.ToVector3() * 0.5f; //set the ambient material.Lights.AddDirectionalLight(true, lightDirection, Color.Gray); //add the first of two light sources material.Lights.AddDirectionalLight(true, -lightDirection, Color.DarkSlateBlue); material.SpecularColour = Color.LightYellow.ToVector3(); //give the material a nice sheen //create a simpler shader to display the wireframe (and also used for the bounding cube) Xen.Ex.Shaders.FillSolidColour simpleShader = new Xen.Ex.Shaders.FillSolidColour(); simpleShader.FillColour = Vector4.One * 0.01f; Vector3 sphereSize = new Vector3(0.5f, 0.5f, 0.5f); //create the complex sphere, this will have ~100k triangles. //pass in a shader for wireframe rendering sphere = new GeometryDrawer(new Xen.Ex.Geometry.Sphere(sphereSize, 200), material, simpleShader); //create the bounding cube sphereBoundingBox = new GeometryDrawer(new Xen.Ex.Geometry.Cube(sphereSize), simpleShader, null); //create the occluding cube, and position it close to the camera cube = new GeometryDrawer(new Xen.Ex.Geometry.Cube(Vector3.One), material, null); cube.position = new Vector3(0, 0, 2.75f); //add the cube first (so it can draw first, potentially occluding the sphere) //if the cube was added second, it would have no effect, as it would draw after the sphere drawToScreen.Add(cube); //create the predicate, passing in the sphere and bounding box Xen.Ex.Scene.DrawPredicate predicate = new Xen.Ex.Scene.DrawPredicate(sphere, sphereBoundingBox); //add the DrawPredicate (the DrawPredicate draws it's children) drawToScreen.Add(predicate); //statistic overlay statOverlay = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(statOverlay); }
protected override void Initialise() { //initialize the physic stuff! physics = new PhysicsSystem(); physics.CollisionSystem = new CollisionSystemSAP(); //all draw targets need a default camera. //create a 3D camera var camera = new Xen.Camera.FirstPersonControlledCamera3D(this.UpdateManager, Vector3.Zero, false); //don't allow the camera to move too fast camera.MovementSensitivity *= 0.1f; camera.LookAt(new Vector3(0.0f, 100.0f, 0.0f), new Vector3(640.0f, 300.0f, 640.0f), Vector3.Up); console = new Console(400, 200); //create the draw target. this.drawToScreen = new DrawTargetScreen(camera); //Set the screen clear colour to blue //(Draw targets have a built in ClearBuffer object) this.drawToScreen.ClearBuffer.ClearColour = Color.CornflowerBlue; //create new actor ("tiny") actor = new Actor(this.Content, "tiny_4anim", Vector3.Zero, 1f); skydome = new Skydome(Content, new Vector3(500,100,700), 1000f); //at runtime, pressing 'F12' will toggle the overlay (or holding both thumbsticks on x360) this.statisticsOverlay = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); TerrainDrawer terrain = new TerrainDrawer(this.Content, Vector3.Zero); drawToScreen.Add(terrain); drawToScreen.Add(skydome); //add statistics to screen drawToScreen.Add(statisticsOverlay); //add console to screen drawToScreen.Add(console.getTextElementRect()); //add actor to the screen drawToScreen.Add(actor); }
protected override void Initialise() { Resource.EnableResourceTracking(); //create the draw target. drawToScreen = new DrawTargetScreen(this, new Camera2D()); drawToScreen.ClearBuffer.ClearColour = Color.CornflowerBlue; //create the GameStateManager GameStateManager manager = new GameStateManager(this); //add it to the screen, and to be updated this.drawToScreen.Add(manager); this.UpdateManager.Add(manager); stats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); this.drawToScreen.Add(stats); }
protected override void Initialise() { Resource.EnableResourceTracking(); //draw targets usually need a camera. Xen.Ex.Camera.FirstPersonControlledCamera3D camera = new Xen.Ex.Camera.FirstPersonControlledCamera3D(this.UpdateManager); //don't allow the camera to move camera.MovementSensitivity *= 0; camera.Position = new Vector3(0, 5, 0); //create the draw target. drawToScreen = new DrawTargetScreen(this, camera); drawToScreen.ClearBuffer.ClearColour = new Color(64, 64, 64); //create the particle system this.particles = new ParticleSystem(this.UpdateManager); //the snow particles will be drawn as velocity particles this.snowDrawer = new Xen.Ex.Graphics.Display.VelocityBillboardParticles3D(this.particles, false, 0.1f); //the fog particles will be drawn as normal billboards this.fogDrawer = new Xen.Ex.Graphics.Display.BillboardParticles3D(this.particles); //add a ground plane to show the horizon drawToScreen.Add(new DarkGroundPlane(new Vector4(0.225f, 0.225f, 0.225f, 1f))); //add the particles drawToScreen.Add(fogDrawer); drawToScreen.Add(snowDrawer); //Note: The particle drawers are masked in the LoadContent method //add draw stats stats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(stats); }
protected override void Initialise() { Resource.EnableResourceTracking(); Camera3D camera = new Xen.Ex.Camera.FirstPersonControlledCamera3D(this.UpdateManager, Vector3.Zero, true); //create the draw target. drawToScreen = new DrawTargetScreen(this, camera); drawToScreen.ClearBuffer.ClearColour = Color.CornflowerBlue; //NEW CODE //create a BatchModel, this class stores the ModelData and will draw BatchModelInstances this.batchModel = new BatchModel(); //NEW CODE //create a large number of actors (1600) for (float x = -20; x < 20; x++) { for (float y = -20; y < 20; y++) { drawToScreen.Add(new Actor(this.batchModel, new Vector3(x * 5, y * 5, -5))); } } //this is the most important bit... //always add the BatchModel itself to the draw target, //this should be added *after* all BatchModelInstances have been added //Note: each time a BatchModelInstance is drawn, it will store it's world matrix in the BatchModel //If the BatchModel is not drawn, the buffer storing these matrices will not be emptied, and will //eventually throw an OutOfMemoryException exception. this.drawToScreen.Add(batchModel); statistics = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); this.drawToScreen.Add(statistics); }
protected override void Initialise() { Camera3D camera = new Camera3D(); camera.LookAt(Vector3.Zero, new Vector3(0, 0, 5), Vector3.UnitY); //create the draw target. drawToScreen = new DrawTargetScreen(camera); drawToScreen.ClearBuffer.ClearColour = Color.CornflowerBlue; //create a shader to display the geometry (this is the same as tutorial 02) var lightDirection = new Vector3(1.0f, 0.5f, 0.5f); var material = new MaterialShader(); material.SpecularColour = Color.LightYellow.ToVector3(); //give the material a nice sheen var lights = new MaterialLightCollection(); lights.AmbientLightColour = Color.CornflowerBlue.ToVector3() * 0.5f; //set the ambient lights.CreateDirectionalLight(lightDirection, Color.Gray); //add the first of two light sources lights.CreateDirectionalLight(-lightDirection, Color.DarkSlateBlue); material.LightCollection = lights; //create a simpler shader to display the wireframe (and also used for the bounding cube) var simpleShader = new Xen.Ex.Shaders.FillSolidColour(); simpleShader.FillColour = Vector4.One * 0.01f; var sphereSize = new Vector3(0.5f, 0.5f, 0.5f); //create the complex sphere, this will have ~100k triangles. //pass in a shader for wireframe rendering sphere = new GeometryDrawer(new Xen.Ex.Geometry.Sphere(sphereSize, 200), material, simpleShader); //create the bounding cube sphereBoundingBox = new GeometryDrawer(new Xen.Ex.Geometry.Cube(sphereSize), simpleShader, null); //create the occluding cube, and position it close to the camera cube = new GeometryDrawer(new Xen.Ex.Geometry.Cube(Vector3.One), material, null); cube.position = new Vector3(0, 0, 2.75f); //add the cube first (so it can draw first, potentially occluding the sphere) //if the cube was added second, it would have no effect, as it would draw after the sphere drawToScreen.Add(cube); //create the predicate, passing in the sphere and bounding box var predicate = new Xen.Ex.Scene.DrawPredicate(sphere, sphereBoundingBox); //add the DrawPredicate (the DrawPredicate draws it's children) drawToScreen.Add(predicate); //statistic overlay statOverlay = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(statOverlay); }
protected override void Initialise() { camera = new Camera3D(); camera.Projection.FarClip = 300; camera.Projection.NearClip = 10; camera.Projection.FieldOfView *= 0.55f; //create the draw target. drawToScreen = new DrawTargetScreen(camera); //no need to clear the colour buffer, as a special background will be drawn drawToScreen.ClearBuffer.ClearColourEnabled = false; //create the light collection first lights = new MaterialLightCollection(); // In this example, the rendering order has been manually optimized to reduce the number of pixels drawn // // In xen, rendering is usually explicit. This means, when a call to Draw() is made, the draw order is // respected, and internally the object will be drawn using the graphics API. // Objects added to the screen will have Draw() called in the order they were added. // // However, the draw order can also cause performance problems. // In general, it's best to draw front to back, this means draw the objects closest to the screen first. // // This way, the objects at the back will be drawing behind the objects already drawn. // Modern video cards can quickly discard pixels if they are 'behind' what is already drawn. // Without front-to-back, the objects at the front could be drawing *over* objects already drawn. // // This is known as overdraw, a case where an object is drawn, only to be 'overdrawn' later in the frame. // Reducing overdraw can help performance, especially when complex shaders are used. // // In this example, the sample is usually vertex-limited (that is, the bottleneck is vertex processing) // However, it can demonstrate how optimizing for overdraw can significantly reduce the number of pixels // that are shaded. // // In debug builds, the DrawStatisticsDisplay class will show the number of pixels drawn in the frame. // // With overdraw optimized draw order, ~1,000,000 pixels are drawn per frame. Without, upto 2,100,000 // pixels are drawn per frame (usually ~1,800,000). (A 1280x720 display has 921,600 pixels) // // This means that without an overdraw optimized draw order, on average, each pixel is being drawn // twice. With an optimized draw order, this number is closer to 1.1, which is very close to the // optimal value of 1.0 (where each pixel is only drawn once). // // Note that the number of pixels reported by the DrawStatisticsDisplay is for the entire frame, including // every render target. Some PCs may not support this value, and display -1. // // One last point.... // This sample is an extreme test of a GPU's ability to push triangles onto the screen (vertex/triangle rate). // However, observation will show the number of triangles drawn is often over 3,300,000! // Assuming half the triangles are back-face culled (an accurate approximation), this still means // there are around 1,650,000 triangles that are visible at any time. // (But remember, the vertex shader still runs for back facing triangles!) // // Assuming approximatly half of these triangles are depth occluded (very approximate), still // results in a huge number of visible triangles. // This all means that the average triangle is drawing a *very* small number of pixels, in this case, // the average for the actors is probably *less than 1 pixel per triangle!*. // // Triangles averaging less than 1 pixel are known as subpixel triangles. // For a number of reasons, subpixel triangles are very inefficent. // For example, if a single pixel is drawn, due to the way a video card works, the pixel shader will always // run in multiples of 4 pixels, so a single pixel triangle will still run the pixel shader 4 times. // // As an approximate rule: // Typically drawing a 1 pixel triangle will be as no faster than drawing a 16 pixel triangle. // // This makes this sample a perfect candidate for level of detail optimization, where a lower resolution // model is used as an actor gets further away from the screen. (Eg, two modelInstances, sharing a controller) // // The vertex shader is also very expensive, and for each triangle, it will be run upto 3 times. // This means the vertex shader is running more often than the pixel shader! // This hypothesis can be confirmed; setting the lights to per-vertex, instead of per-pixel, results // in a significantly *lower* frame rate! // // // bool optimizeForOverdraw = true; //create a list of actors to added to the screen var actors = new List<Actor>(500); //create 500 actors! for (int i = 0; i < 500; i++) { Actor actor = new Actor(this.Content, this.UpdateManager, lights, diskRadius); actors.Add(actor); } //create the lights, similar to Tutorial 14 lights.AmbientLightColour = new Vector3(0.35f, 0.35f, 0.45f); Vector3[] lightPositions = { new Vector3(0, 30, 12), new Vector3(0, -30, 12) }; //setup the two lights in the scene IDraw lightGeometry = null; IDraw lightPoleGeometry = null; //create geometry to display the lights var lightSourceGeometry = new List<IDraw>(); //setup the lights, and create the light globe geometry for (int i = 0; i < lightPositions.Length; i++) { var colour = new Vector3(2, 2, 2); var light = lights.CreatePointLight(lightPositions[i], 1, colour, colour); light.SourceRadius = 6; if (lightGeometry == null) { lightGeometry = new Xen.Ex.Geometry.Sphere(Vector3.One, 8, true, false, false); lightPoleGeometry = new Xen.Ex.Geometry.Cube(new Vector3(0.4f, 0.4f, lightPositions[i].Z * 0.5f)); } //visually show the light //create the light sphere geometry from tutorial 14. var position = lightPositions[i]; lightSourceGeometry.Add(new Tutorial_14.LightSourceDrawer(position, lightGeometry, Color.LightYellow)); position.Z *= 0.5f; lightSourceGeometry.Add(new Tutorial_14.LightSourceDrawer(position, lightPoleGeometry, new Color(40,40,70))); } //create the ground plane, also from tutorial 14 var ground = new Tutorial_14.GroundDisk(this.Content, lights, diskRadius); //this is a special background element, //it draws a gradient over the entire screen, fading from dark at the bottom to light at the top. Color darkBlue = new Color(40, 40, 50); Color lightBlue = new Color(100, 100, 110); var background = new BackgroundGradient(lightBlue, darkBlue); if (optimizeForOverdraw == false) { //add all the objects in a naive order //first add the background (fills the entire screen, draws to every pixel, but is very fast) drawToScreen.Add(background); //then add the ground plane (all the actors will appear on top of the ground plane, overdrawing it) drawToScreen.Add(ground); //then add the lights (which are on top of the ground, overdrawing it) foreach (IDraw geometry in lightSourceGeometry) drawToScreen.Add(geometry); //then finally add the actors, in the order they were created foreach (Actor actor in actors) drawToScreen.Add(actor); } else { //or, add the objects in a order optimized for overdraw #if !XBOX360 //first, add the actors. Because they are almost always closest to the screen //however, use a depth sorter so the actors are sorted into a front to back draw order, //this sorting is based on the centre point of the cull tests they perform. var sorter = new Xen.Ex.Scene.DepthDrawSorter(Xen.Ex.Scene.DepthSortMode.FrontToBack); //Remember, the objects placed in the sorter *must* perform a valid CullTest, //if the CullTest simply returns true/false, no sorting will occur. //(Note the Actor.CullTest method) //to ease the CPU load, have the sorter only sort the actors every few frames... sorter.SortDelayFrameCount = 5; foreach (Actor actor in actors) sorter.Add(actor); // add the actors to the sorter (not the screen) //the sorter itself must be added to the screen! drawToScreen.Add(sorter); // the sorter will then draw the actors in a sorted order #else //In this case (on the Xbox), because the application is heavily vertex limited //and already heavily CPU stretched by the animation system, the cost of //sorting the actors actually causes a larger performance hit on the CPU than //the time saved on the GPU. This inballance causes a frame rate drop. // //However, the reason for this may be unexpected. //The framerate drop is not caused by the overhead of sorting the actors. // //Any 3D API calls made are doubly expensive on the XBOX, so in order to //maintain 20fps in this sample, the primary (rendering) thread must not //block, or switch to task processing. //If it does so, valuable rendering time is lost. // //When using a sorter, the actors are drawn in an order that is constantly changing. //However, they always have Update() called in a consistent order. // //During Update() the actors animation controllers will spawn thread tasks to //process their animation. // //These tasks are processed on the spare xbox hardware threads, they are //processed in the order they were added. //Processing the animation usually completes before the rendering finishes. //(the rendering is not delayed waiting for the animation to finish). // //However, when sorting the actors get drawn in an unpredictable order, //this means the last actor added could be the first actor to draw, //in such a case, the chances of it's animation processing having completed //is *very* low. When this happens, the rendering thread has to switch to //processing animations, delaying rendering. // //So, for the xbox, in this sample it's best just to draw in the update order. foreach (Actor actor in actors) drawToScreen.Add(actor); #endif //add the light source geometry, as they are usually below the actors, but above the ground foreach (IDraw geometry in lightSourceGeometry) drawToScreen.Add(geometry); //then add the ground plane, which is usually below the actors and lights. drawToScreen.Add(ground); //finally, enable a special feature of ElementRect. //This makes the element draw at the maximum possible Z distance //(behind anything else that has been drawn) background.DrawAtMaxZDepth = true; //add it to the screen drawToScreen.Add(background); } //finally, //create the draw statistics display stats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(stats); }
protected override void Initialise() { Resource.EnableResourceTracking(); camera = new Camera3D(); camera.Projection.FarClip = 300; camera.Projection.NearClip = 10; camera.Projection.FieldOfView *= 0.55f; //create the draw target. drawToScreen = new DrawTargetScreen(this, camera); //no need to clear the colour buffer, as a special background will be drawn drawToScreen.ClearBuffer.ClearColourEnabled = false; //create the light collection first lights = new MaterialLightCollection(); // In this example, the rendering order has been manually optimized to reduce the number of pixels drawn // // In xen, rendering is usually explicit. This means, when a call to Draw() is made, the draw order is // respected, and internally the object will be drawn using the graphics API. // Objects added to the screen will have Draw() called in the order they were added. // // However, the draw order can also cause performance problems. // In general, it's best to draw front to back, this means draw the objects closest to the screen first. // // This way, the objects at the back will be drawing behind the objects already drawn. // Modern video cards can quickly discard pixels if they are 'behind' what is already drawn. // Without front-to-back, the objects at the front could be drawing *over* objects already drawn. // // This is known as overdraw, a case where an object is drawn, only to be 'overdrawn' later in the frame. // Reducing overdraw can help performance, especially when complex shaders are used. // // In this example, the sample is usually vertex-limited (that is, the bottleneck is vertex processing) // However, it can demonstrate how optimizing for overdraw can significantly reduce the number of pixels // that are shaded. // // In debug builds, the DrawStatisticsDisplay class will show the number of pixels drawn in the frame. // // With overdraw optimized draw order, ~1,000,000 pixels are drawn per frame. Without, upto 2,100,000 // pixels are drawn per frame (usually ~1,800,000). (A 1280x720 display has 921,600 pixels) // // This means that without an overdraw optimized draw order, on average, each pixel is being drawn // twice. With an optimized draw order, this number is closer to 1.1, which is very close to the // optimal value of 1.0 (where each pixel is only drawn once). // // Note that the number of pixels reported by the DrawStatisticsDisplay is for the entire frame, including // every render target. Some PCs may not support this value, and display -1. // // One last point.... // This sample is an extreme test of a GPU's ability to push triangles onto the screen (vertex/triangle rate). // However, observation will show the number of triangles drawn is often over 3,300,000! // Assuming half the triangles are back-face culled (an accurate approximation), this still means // there are around 1,650,000 triangles that are visible at any time. // (But remember, the vertex shader still runs for back facing triangles!) // // Assuming approximatly half of these triangles are depth occluded (very approximate), still // results in a huge number of visible triangles. // This all means that the average triangle is drawing a *very* small number of pixels, in this case, // the average for the actors is probably *less than 1 pixel per triangle!*. // // Triangles averaging less than 1 pixel are known as subpixel triangles. // For a number of reasons, subpixel triangles are very inefficent. // For example, if a single pixel is drawn, due to the way a video card works, the pixel shader will always // run in multiples of 4 pixels, so a single pixel triangle will still run the pixel shader 4 times. // // This makes this sample a perfect candidate for level of detail optimization, where a lower resolution // model is used as an actor gets further away from the screen. // // The vertex shader is also very expensive, and for each triangle, it will be run upto 3 times. // This means the vertex shader is quite possibly running more often than the pixel shader. // This hypothesis can be confirmed; setting the lights to per-vertex, instead of per-pixel, results // in a significantly *lower* frame rate! // // // bool optimizeForOverdraw = true; //create a list of actors to added to the screen List <Actor> actors = new List <Actor>(500); //create 500 actors! for (int i = 0; i < 500; i++) { Actor actor = new Actor(this.Content, this.UpdateManager, lights, diskRadius); actors.Add(actor); } //create the lights, similar to Tutorial 14 lights.AmbientLightColour = new Vector3(0.45f, 0.45f, 0.5f); Vector3[] lightPositions = new Vector3[] { new Vector3(0, 30, 12), new Vector3(0, -30, 12) }; //setup the two lights in the scene IDraw lightGeometry = null; IDraw lightPoleGeometry = null; //create geometry to display the lights List <IDraw> lightSourceGeometry = new List <IDraw>(); //setup the lights, and create the light globe geometry for (int i = 0; i < lightPositions.Length; i++) { Vector3 colour = new Vector3(5, 5, 5); IMaterialPointLight light = lights.AddPointLight(i < 2, lightPositions[i], 8, colour, colour); light.ConstantAttenuation = 0.25f; // make the ligh falloff curve a lot sharper (brighter at the centre) light.LinearAttenuation = 0; light.QuadraticAttenuation = 0.075f; //approximate inverse distance in which the brightness of the light will halve if (lightGeometry == null) { lightGeometry = new Xen.Ex.Geometry.Sphere(Vector3.One, 8, true, false, false); lightPoleGeometry = new Xen.Ex.Geometry.Cube(new Vector3(0.4f, 0.4f, lightPositions[i].Z * 0.5f)); } //visually show the light //create the light sphere geometry from tutorial 14. Vector3 position = lightPositions[i]; lightSourceGeometry.Add(new Tutorial_14.LightSourceDrawer(position, lightGeometry, Color.LightYellow)); position.Z *= 0.5f; lightSourceGeometry.Add(new Tutorial_14.LightSourceDrawer(position, lightPoleGeometry, new Color(40, 40, 70))); } //create the ground plane, also from tutorial 14 Tutorial_14.GroundDisk ground = new Tutorial_14.GroundDisk(this.Content, lights, diskRadius); //this is a special background element, //it draws a gradient over the entire screen, fading from dark at the bottom to light at the top. Color darkBlue = new Color(40, 40, 50); Color lightBlue = new Color(100, 100, 110); BackgroundGradient background = new BackgroundGradient(lightBlue, darkBlue); if (optimizeForOverdraw == false) { //add all the objects in a naive order //first add the background (fills the entire screen, draws to every pixel, but is very fast) drawToScreen.Add(background); //then add the ground plane (all the actors will appear on top of the ground plane, overdrawing it) drawToScreen.Add(ground); //then add the lights (which are on top of the ground, overdrawing it) foreach (IDraw geometry in lightSourceGeometry) { drawToScreen.Add(geometry); } //then finally add the actors, in the order they were created foreach (Actor actor in actors) { drawToScreen.Add(actor); } } else { //or, add the objects in a order optimized for overdraw #if !XBOX360 //first, add the actors. Because they are almost always closest to the screen //however, use a depth sorter so the actors are sorted into a front to back draw order, //this sorting is based on the centre point of the cull tests they perform. Xen.Ex.Scene.DepthDrawSorter sorter = new Xen.Ex.Scene.DepthDrawSorter(Xen.Ex.Scene.DepthSortMode.FrontToBack); //Remember, the objects placed in the sorter *must* perform a valid CullTest, //if the CullTest simply returns true/false, no sorting will occur. //(Note the Actor.CullTest method) //to ease the CPU load, have the sorter only sort the actors every few frames... sorter.SortDelayFrameCount = 5; foreach (Actor actor in actors) { sorter.Add(actor); // add the actors to the sorter (not the screen) } //the sorter itself must be added to the screen! drawToScreen.Add(sorter); // the sorter will then draw the actors in a sorted order #else //In this case (on the Xbox), because the application is heavily vertex limited //and already heavily CPU stretched by the animation system, the cost of //sorting the actors actually causes a larger performance hit on the CPU than //the time saved on the GPU. This inballance causes a frame rate drop. // //However, the reason for this may be unexpected. //The framerate drop is not caused by the overhead of sorting the actors. // //Any 3D API calls made are doubly expensive on the XBOX, so in order to //maintain 20fps in this sample, the primary (rendering) thread must not //block, or switch to task processing. //If it does so, valuable rendering time is lost. // //When using a sorter, the actors are drawn in an order that is constantly changing. //However, they always have Update() called in a consistent order. // //During Update() the actors animation controllers will spawn thread tasks to //process their animation. // //These tasks are processed on the three spare xbox hardware threads, they are //processed in the order they were added. //Processing the animation usually completes before the rendering finishes. //(the rendering is not delayed waiting for the animation to finish). // //However, when sorting the actors get drawn in an unpredictable order, //this means the last actor added could be the first actor to draw, //in such a case, the chances of it's animation processing having completed //is *very* low. When this happens, the rendering thread has to switch to //processing animations, delaying rendering. // //So, for the xbox, it's best just to draw in the update order. foreach (Actor actor in actors) { drawToScreen.Add(actor); } #endif //add the light source geometry, as they are usually below the actors, but above the ground foreach (IDraw geometry in lightSourceGeometry) { drawToScreen.Add(geometry); } //then add the ground plane, which is usually below the actors and lights. drawToScreen.Add(ground); //finally, enable a special feature of ElementRect. //This makes the element draw at the maximum possible Z distance //(behind anything else that has been drawn) background.DrawAtMaxZDepth = true; //add it to the screen drawToScreen.Add(background); } //finally, //create the draw statistics display stats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(stats); }
protected override void Initialise() { //create the draw target. drawToScreen = new DrawTargetScreen(new Camera2D()); drawToScreen.ClearBuffer.ClearColour = Color.CornflowerBlue; //create the GameStateManager GameStateManager manager = new GameStateManager(this); //add it to the screen, and to be updated this.drawToScreen.Add(manager); this.UpdateManager.Add(manager); stats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); this.drawToScreen.Add(stats); }
protected override void Initialise() { //draw targets usually need a camera. var camera = new Xen.Camera.FirstPersonControlledCamera3D(this.UpdateManager, Vector3.Zero, false); //don't allow the camera to move too fast camera.MovementSensitivity *= 0.1f; camera.LookAt(new Vector3(0,3,0), new Vector3(1, 5, 10), new Vector3(0, 1, 0)); //create the draw target. drawToScreen = new DrawTargetScreen(camera); drawToScreen.ClearBuffer.ClearColour = new Color(45,50,60); //create the fire and smoke particle system this.fireParticleSystem = new ParticleSystem(this.UpdateManager); this.smokeParticleSystem = new ParticleSystem(this.UpdateManager); //IMPORTANT //The following flags are FALSE by default. //For looping effects, such as the fire and smoke, it's highly //recommended to enable this flag. Otherwise, while the effect //is offscreen, the particle system will continue to process. this.fireParticleSystem.PauseUpdatingWhileCulled = true; this.smokeParticleSystem.PauseUpdatingWhileCulled = true; this.drawSorted = new Xen.Ex.Scene.DepthDrawSorter(Xen.Ex.Scene.DepthSortMode.BackToFront); this.drawUnsorted = new DrawList(); var fireDrawer = new Xen.Ex.Graphics.Display.VelocityBillboardParticles3D(this.fireParticleSystem, true); var smokeDrawer = new Xen.Ex.Graphics.Display.BillboardParticles3D(this.smokeParticleSystem); for (int i = 0; i < 10; i++) { Vector3 position = new Vector3((float)Math.Cos(i * Math.PI / 5.0) * 6.0f, 0, (float)Math.Sin(i * Math.PI / 5.0) * 6.0f); CullableParticleWrapper fireEffect, smokeEffect; fireEffect = new CullableParticleWrapper(fireDrawer, position, new Vector3(0, 2, 0), 4); smokeEffect = new CullableParticleWrapper(smokeDrawer, position, new Vector3(0, 6, 0), 5); this.drawSorted.Add(fireEffect); this.drawSorted.Add(smokeEffect); this.drawUnsorted.Add(fireEffect); this.drawUnsorted.Add(smokeEffect); var light = new GroundLightDisk(position); this.drawSorted.Add(light); this.drawUnsorted.Add(light); } //setup the burst effect this.burstParticleSystem = new ParticleSystem(this.UpdateManager); //for this case, PauseUpdatingWhileCulled is not set to true. //The particle emitting is culled when offscreen. If set to true, //Any particles left offscreen could 'pause', when they naturally //wouldn't be emitted anyway. //(The particle system will use very few resources when it has no //active particles) this.burstSources = new BurstSource[20]; Random rand = new Random(); for (int i = 0; i < this.burstSources.Length; i++) { //create the bursts out in the distance Vector3 position = new Vector3((float)i * 5.0f - this.burstSources.Length * 2.5f, 0, -20); float radius = 10; // with a decent radius //give them a random starting time this.burstSources[i] = new BurstSource(position, radius, (float)rand.NextDouble() * 2); this.drawSorted.Add(this.burstSources[i]); this.drawUnsorted.Add(this.burstSources[i]); } //the bursts need to be drawn as a group.. var burstDrawer = new Xen.Ex.Graphics.Display.VelocityBillboardParticles3D(this.burstParticleSystem,false,0.5f); this.drawSorted.Add(burstDrawer); this.drawUnsorted.Add(burstDrawer); //Use all the burst sources to cull the drawer (may not be ideal if there were many sources...) //Use the particle drawer CullProxy to do it burstDrawer.CullProxy = new BurstCullProxy(this.burstSources); //add a ground plane to show the horizon drawToScreen.Add(new Tutorial_22.DarkGroundPlane(new Vector4(0.125f,0.15f,0.135f,1))); //add the sorted and unsorted lists drawToScreen.Add(drawSorted); drawToScreen.Add(drawUnsorted); //finally, create a CullTestVisualizer, which will visually show the cull tests performed cullTestVisualizer = new Xen.Ex.Scene.CullTestVisualizer(); //the visualizer is added as a draw modifier this.drawToScreen.AddModifier(cullTestVisualizer); //add help text this.text = new TextElement(); this.text.VerticalAlignment = VerticalAlignment.Bottom; this.text.Position = new Vector2(50, 100); drawToScreen.Add(this.text); //add draw stats stats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(stats); }
protected override void Initialise() { Resource.EnableResourceTracking(); //draw targets usually need a camera. Xen.Ex.Camera.FirstPersonControlledCamera3D camera = new Xen.Ex.Camera.FirstPersonControlledCamera3D(this.UpdateManager, Vector3.Zero, false); //don't allow the camera to move too fast camera.MovementSensitivity *= 0.1f; camera.LookAt(new Vector3(0, 3, 0), new Vector3(1, 5, 10), new Vector3(0, 1, 0)); //create the draw target. drawToScreen = new DrawTargetScreen(this, camera); drawToScreen.ClearBuffer.ClearColour = new Color(45, 50, 60); //create the fire and smoke particle system this.fireParticleSystem = new ParticleSystem(this.UpdateManager); this.smokeParticleSystem = new ParticleSystem(this.UpdateManager); //IMPORTANT //The following flags are FALSE by default. //For looping effects, such as the fire and smoke, it's highly //recommended to enable this flag. Otherwise, while the effect //is offscreen, the particle system will continue to process. this.fireParticleSystem.PauseUpdatingWhileCulled = true; this.smokeParticleSystem.PauseUpdatingWhileCulled = true; this.drawSorted = new Xen.Ex.Scene.DepthDrawSorter(Xen.Ex.Scene.DepthSortMode.BackToFront); this.drawUnsorted = new DrawList(); Xen.Ex.Graphics.Display.ParticleDrawer3D fireDrawer = new Xen.Ex.Graphics.Display.VelocityBillboardParticles3D(this.fireParticleSystem, true); Xen.Ex.Graphics.Display.ParticleDrawer3D smokeDrawer = new Xen.Ex.Graphics.Display.BillboardParticles3D(this.smokeParticleSystem); for (int i = 0; i < 10; i++) { Vector3 position = new Vector3((float)Math.Cos(i * Math.PI / 5.0) * 6.0f, 0, (float)Math.Sin(i * Math.PI / 5.0) * 6.0f); CullableParticleWrapper fireEffect, smokeEffect; fireEffect = new CullableParticleWrapper(fireDrawer, position, new Vector3(0, 2, 0), 4); smokeEffect = new CullableParticleWrapper(smokeDrawer, position, new Vector3(0, 6, 0), 5); this.drawSorted.Add(fireEffect); this.drawSorted.Add(smokeEffect); this.drawUnsorted.Add(fireEffect); this.drawUnsorted.Add(smokeEffect); GroundLightDisk light = new GroundLightDisk(position); this.drawSorted.Add(light); this.drawUnsorted.Add(light); } //setup the burst effect this.burstParticleSystem = new ParticleSystem(this.UpdateManager); //for this case, PauseUpdatingWhileCulled is not set to true. //The particle emitting is culled when offscreen. If set to true, //Any particles left offscreen could 'pause', when they naturally //wouldn't be emitted anyway. //(The particle system will use very few resources when it has no //active particles) this.burstSources = new BurstSource[20]; Random rand = new Random(); for (int i = 0; i < this.burstSources.Length; i++) { //create the bursts out in the distance Vector3 position = new Vector3((float)i * 5.0f - this.burstSources.Length * 2.5f, 0, -20); float radius = 10; // with a decent radius //give them a random starting time this.burstSources[i] = new BurstSource(position, radius, (float)rand.NextDouble() * 2); this.drawSorted.Add(this.burstSources[i]); this.drawUnsorted.Add(this.burstSources[i]); } //the bursts need to be drawn as a group.. ParticleDrawer3D burstDrawer = new Xen.Ex.Graphics.Display.VelocityBillboardParticles3D(this.burstParticleSystem, false, 0.5f); this.drawSorted.Add(burstDrawer); this.drawUnsorted.Add(burstDrawer); //Use all the burst sources to cull the drawer (may not be ideal if there were many sources...) //Use the particle drawer CullProxy to do it burstDrawer.CullProxy = new BurstCullProxy(this.burstSources); //add a ground plane to show the horizon drawToScreen.Add(new Tutorial_22.DarkGroundPlane(new Vector4(0.125f, 0.15f, 0.135f, 1))); //add the sorted and unsorted lists drawToScreen.Add(drawSorted); drawToScreen.Add(drawUnsorted); //finally, create a CullTestVisualizer, which will visually show the cull tests performed cullTestVisualizer = new Xen.Ex.Scene.CullTestVisualizer(this.drawToScreen.Camera); //the visualizer is added as a draw modifier this.drawToScreen.AddModifier(cullTestVisualizer); //add help text this.text = new TextElement(); this.text.VerticalAlignment = VerticalAlignment.Bottom; this.text.Position = new Vector2(50, 100); drawToScreen.Add(this.text); //add draw stats stats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(stats); }
protected override void Initialise() { //setup the view camera first //-------------------------------------- viewCamera = new Xen.Camera.FirstPersonControlledCamera3D(this.UpdateManager); viewCamera.Projection.FieldOfView *= 0.65f; viewCamera.MovementSensitivity *= 0.05f; viewCamera.LookAt(new Vector3(-3, 4, 2), new Vector3(6, 6, 2), new Vector3(0, 1, 0)); viewCamera.Projection.NearClip = 0.1f; //shadow map setup: //-------------------------------------- const float shadowArea = 4; const int shadowMapResolution = 1024; //setup the shadow map rendering camera shadowCamera = new Camera3D(); //setup the shadow map projection to roughly cover the character shadowCamera.Projection.Orthographic = true; shadowCamera.Projection.NearClip = shadowArea * 2; shadowCamera.Projection.FarClip = -shadowArea * 2; shadowCamera.Projection.Region = new Vector4(1, -1.8f, -1, 0.2f) * shadowArea; //setup the shadow map draw target //create the shadow map shadowMap = new DrawTargetTexture2D(shadowCamera, shadowMapResolution, shadowMapResolution, SurfaceFormat.HalfSingle, DepthFormat.Depth24); shadowMap.ClearBuffer.ClearColour = Color.White; //setup the shadow map drawer.. shadowDrawer = new Tutorial_25.ShadowMapDrawer(null, new Tutorial_25.ShadowOutputShaderProvider()); this.shadowMap.Add(shadowDrawer); //create the main draw targets. //-------------------------------------- drawToScreen = new DrawTargetScreen(new Camera2D()); drawToScreen.ClearBuffer.ClearColourEnabled = false; drawToRenderTarget = new DrawTargetTexture2D(viewCamera, this.WindowWidth, this.WindowHeight, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, false, PreferredMultiSampleLevel.FourSamples, RenderTargetUsage.PlatformContents); drawToRenderTarget.ClearBuffer.ClearColourEnabled = false; //setup the bloom draw targets //-------------------------------------- //scale to reduce the size of the bloom target, compared to main render target const int bloomDownsample = 8; //eight times smaller bloomRenderTarget = new DrawTargetTexture2D(new Camera2D(), Math.Max(1, drawToRenderTarget.Width / bloomDownsample), Math.Max(1, drawToRenderTarget.Height / bloomDownsample), SurfaceFormat.Color, DepthFormat.None); bloomRenderTarget.ClearBuffer.ClearColourEnabled = false; bloomIntermediateRenderTarget = null; //the bloom intermediate target is not needed on the xbox, as the full bloom target fits in EDRAM bloomIntermediateRenderTarget = new DrawTargetTexture2D(viewCamera, bloomRenderTarget.Width, bloomRenderTarget.Height, SurfaceFormat.Color, DepthFormat.None); bloomIntermediateRenderTarget.ClearBuffer.ClearColourEnabled = false; //setup the blur filter, with a large 31 sample radius. bloomBlurPass = new Xen.Ex.Filters.BlurFilter(Xen.Ex.Filters.BlurFilterFormat.ThirtyOneSampleBlur_FilteredTextureFormat, 1.0f, bloomRenderTarget, bloomIntermediateRenderTarget); //setup the character model this.model = new ModelInstance(); //(the model is setup in LoadContent) this.modelRotation = new DrawRotated(model); this.modelRotation.RotationAngle = 3; //add the model to be drawn drawToRenderTarget.Add(modelRotation); //setup the shaders this.characterRenderShader = new Shaders.Character(); //setup the output and bloom shaders outputShader = new Shaders.RgbmDecode(); drawToScreen.Add(new ShaderElement(outputShader, new Vector2(1, 1), true)); bloomPassShader = new Shaders.RgbmDecodeBloomPass(); bloomRenderTarget.Add(new ShaderElement(bloomPassShader, new Vector2(1, 1), true)); //add a background to be drawn drawToRenderTarget.Add(new BackgroundDrawer()); //setup the debug image displays //-------------------------------------- this.rgmbTextureAlphaShader = new Shaders.AlphaWrite(); this.bloomTextureDisplay = new TexturedElement(this.bloomRenderTarget, new Vector2(0.2f, 0.2f), true); this.rgbmTextureDisplay = new TexturedElement(this.drawToRenderTarget, new Vector2(0.2f, 0.2f), true); this.rgbmTextureAlphaDisplay = new ShaderElement(this.rgmbTextureAlphaShader, new Vector2(0.2f, 0.2f), true); this.rgbmTextureAlphaDisplay.Position = new Vector2(0.7f, 0.2f); this.rgbmTextureDisplay.Position = new Vector2(0.7f, 0.4f); this.bloomTextureDisplay.Position = new Vector2(0.7f, 0.6f); this.drawToScreen.Add(this.rgbmTextureDisplay); this.drawToScreen.Add(this.rgbmTextureAlphaDisplay); this.drawToScreen.Add(this.bloomTextureDisplay); //setup the render config this.configEditor = new RenderConfigEditor(this.Content); this.drawToScreen.Add(configEditor); this.UpdateManager.Add(configEditor); //add a statistics overlay. drawStats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(drawStats); }
protected override void Initialise() { //DrawStatisticsDisplay requires that resource tracking is enabled Resource.EnableResourceTracking(); //Xen.Ex provides a very useful Camera3D called 'FirstPersonControlledCamera3D'. //This camera uses player input to act as a simple first-person style flythrough camera Xen.Ex.Camera.FirstPersonControlledCamera3D camera = null; //it uses player input, so the UpdateManager must be passed in camera = new Xen.Ex.Camera.FirstPersonControlledCamera3D(this.UpdateManager); //in this case, we want the z-axis to be the up/down axis (otherwise it's the Y-axis) camera.ZAxisUp = true; //also it's default is a bit too fast moving camera.MovementSensitivity *= 0.1f; camera.LookAt(new Vector3(1, 0, 0), new Vector3(), new Vector3(0, 0, 1)); this.camera = camera; //create the draw target. drawToScreen = new DrawTargetScreen(this, camera); //create a large number of actor instance from tutorial 10.. for (int n = 0; n <= 16; n++) { //create in a half circle float angle = (n / 16.0f) * MathHelper.Pi; Vector3 position = new Vector3((float)Math.Sin(angle), (float)Math.Cos(angle), 0); //not too close together position *= 10; drawToScreen.Add(new Tutorial_10.Actor(this.Content, position)); } //this element will display the camera position positionDisplay = new TextElement(); //TextElement (unlike other Elements) defaults to Top Left alignment //So, in order to bring it closer to the centre of the screen (due to potential overscan) //it's position needs to be set 'right' and 'down' from 'top left' //(this is just an example, see XNA docs for correct overscan compensation behaviour) positionDisplay.Position = new Vector2(40, -40); //offset from top left corner alignment //add it to the screen drawToScreen.Add(positionDisplay); Vector2 sizeInPixels = new Vector2(400, 200); //create the main block of yellow text this.yellowElement = new TextElementRect(sizeInPixels); this.yellowElement.Colour = Color.Yellow; //first line of text... this will have a flashing 2D element embedded string embeddedText = @"This is a text box with a large amount of custom text! It also includes an embedded 2D element: , which is a 16x16 SolidColourElement"; uint insertAtIndex = 96; // Hard coded to insert a 2D element at character index 96 which is about here: ^ //add a bunch of text... this.yellowElement.Text.AppendLine(embeddedText); this.yellowElement.Text.AppendLine(); this.yellowElement.Text.AppendLine(@"This class is:"); this.yellowElement.Text.AppendLine(this.GetType().FullName); this.yellowElement.Text.AppendLine(@"It is located in assembly:"); this.yellowElement.Text.AppendLine(this.GetType().Assembly.FullName); this.yellowElement.Text.AppendLine(); //add an embedded 2D element within the text //create it.. this.embeddedElement = new SolidColourElement(Color.Red, new Vector2(16, 16)); // quite small this.embeddedElement.AlphaBlendState = AlphaBlendState.Alpha; //add it. this.yellowElement.AddInline(this.embeddedElement, insertAtIndex); #if XBOX360 this.yellowElement.Text.AppendLine(@"Press and hold both thumbsticks to show the debug overlay"); #else this.yellowElement.Text.AppendLine(@"Press F12 to show the debug overlay"); #endif //align the element rectangle to the bottom centre of the screen this.yellowElement.VerticalAlignment = VerticalAlignment.Bottom; this.yellowElement.HorizontalAlignment = HorizontalAlignment.Centre; //centre align the text this.yellowElement.TextHorizontalAlignment = TextHorizontalAlignment.Centre; //centre the text in the middle of the 400x200 area of the element rectangle this.yellowElement.TextVerticalAlignment = VerticalAlignment.Centre; //add it to the screen drawToScreen.Add(yellowElement); //create the statistics display //this class will query the DrawState for the previous frames DrawStatistics structure. //this structure provides a large number of statistics for the drawn frame. //The DrawStatisticsDisplay displays some of the more important statistics. It will also //display thread activity on the xbox. //DrawStatistics are only available in DEBUG xen builds //They can be accessed at runtime with DrawState GetPreviousFrameStatistics() //at runtime, pressing 'F12' will toggle the overlay (or holding both thumbsticks on x360) this.statisticsOverlay = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); //As of xen 1.5, by default the DrawStatisticsDisplay displays a significantly reduced number of graphs. //To display the full set of graphs (which generally takes up the entire screen), set the following //property to 'true': //this.statisticsOverlay.DisplayFullGraphList = true; //then add it to the screen drawToScreen.Add(statisticsOverlay); }
protected override void Initialise() { Resource.EnableResourceTracking(); //setup the view camera first //-------------------------------------- viewCamera = new Xen.Ex.Camera.FirstPersonControlledCamera3D(this.UpdateManager); viewCamera.Projection.FieldOfView *= 0.65f; viewCamera.MovementSensitivity *= 0.05f; viewCamera.LookAt(new Vector3(-3, 4, 2), new Vector3(6, 6, 2), new Vector3(0, 1, 0)); viewCamera.Projection.NearClip = 0.1f; //shadow map setup: //-------------------------------------- const float shadowArea = 4; const int shadowMapResolution = 1024; //setup the shadow map rendering camera shadowCamera = new Camera3D(); //setup the shadow map projection to roughly cover the character shadowCamera.Projection.Orthographic = true; shadowCamera.Projection.NearClip = shadowArea * 2; shadowCamera.Projection.FarClip = -shadowArea * 2; shadowCamera.Projection.Region = new Vector4(1, -1.8f, -1, 0.2f) * shadowArea; //setup the shadow map draw target //find a desirable format for the shadow map, SurfaceFormat format = SurfaceFormat.Color; //ideally use a high precision format, but only if it's supported. Avoid full 32bit float if (DrawTargetTexture2D.SupportsFormat(SurfaceFormat.Rg32)) { format = SurfaceFormat.Rg32; //ushort * 2 } else if (DrawTargetTexture2D.SupportsFormat(SurfaceFormat.HalfVector2)) { format = SurfaceFormat.HalfVector2; //fp16 * 2 } else if (DrawTargetTexture2D.SupportsFormat(SurfaceFormat.HalfVector4)) { format = SurfaceFormat.HalfVector4; //fp16 * 4 } //create the shadow map shadowMap = new DrawTargetTexture2D(shadowCamera, shadowMapResolution, shadowMapResolution, format, DepthFormat.Depth24); shadowMap.ClearBuffer.ClearColour = Color.White; //setup the shadow map drawer.. shadowDrawer = new Tutorial_25.ShadowMapDrawer(null, new Tutorial_25.ShadowOutputShaderProvider()); this.shadowMap.Add(shadowDrawer); //create the main draw targets. //-------------------------------------- drawToScreen = new DrawTargetScreen(this, new Camera2D()); drawToScreen.ClearBuffer.ClearColourEnabled = false; drawToRenderTarget = new DrawTargetTexture2D(viewCamera, this.WindowWidth, this.WindowHeight, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, false, MultiSampleType.FourSamples, RenderTargetUsage.PlatformContents); drawToRenderTarget.ClearBuffer.ClearColourEnabled = false; //setup the bloom draw targets //-------------------------------------- //scale to reduce the size of the bloom target, compared to main render target const int bloomDownsample = 8; //eight times smaller bloomRenderTarget = new DrawTargetTexture2D(new Camera2D(), Math.Max(1, drawToRenderTarget.Width / bloomDownsample), Math.Max(1, drawToRenderTarget.Height / bloomDownsample), SurfaceFormat.Color); bloomRenderTarget.ClearBuffer.ClearColourEnabled = false; bloomIntermediateRenderTarget = null; #if WINDOWS //the bloom intermediate target is not needed on the xbox, as the full bloom target fits in EDRAM bloomIntermediateRenderTarget = new DrawTargetTexture2D(viewCamera, bloomRenderTarget.Width, bloomRenderTarget.Height, SurfaceFormat.Color); bloomIntermediateRenderTarget.ClearBuffer.ClearColourEnabled = false; #endif //setup the blur filter, with a large 31 sample radius. bloomBlurPass = new Xen.Ex.Filters.BlurFilter(Xen.Ex.Filters.BlurFilterFormat.ThirtyOneSampleBlur_FilteredTextureFormat, 1.0f, bloomRenderTarget, bloomIntermediateRenderTarget); //setup the character model this.model = new ModelInstance(); //(the model is setup in LoadContent) this.modelRotation = new DrawRotated(model); this.modelRotation.RotationAngle = 3; //add the model to be drawn drawToRenderTarget.Add(modelRotation); //setup the shaders this.characterRenderShader = new Shaders.Character(); this.characterBlendRenderShader = new Shaders.CharacterBlend(); //setup the output and bloom shaders outputShader = new Shaders.RgbmDecode(); drawToScreen.Add(new ShaderElement(outputShader, new Vector2(1, 1), true)); bloomPassShader = new Shaders.RgbmDecodeBloomPass(); bloomRenderTarget.Add(new ShaderElement(bloomPassShader, new Vector2(1, 1), true)); //add a background to be drawn drawToRenderTarget.Add(new BackgroundDrawer()); //setup the debug image displays //-------------------------------------- this.rgmbTextureAlphaShader = new Shaders.AlphaWrite(); this.bloomTextureDisplay = new TexturedElement(this.bloomRenderTarget, new Vector2(0.2f, 0.2f), true); this.rgbmTextureDisplay = new TexturedElement(this.drawToRenderTarget, new Vector2(0.2f, 0.2f), true); this.rgbmTextureAlphaDisplay = new ShaderElement(this.rgmbTextureAlphaShader, new Vector2(0.2f, 0.2f), true); this.rgbmTextureAlphaDisplay.Position = new Vector2(0.7f, 0.2f); this.rgbmTextureDisplay.Position = new Vector2(0.7f, 0.4f); this.bloomTextureDisplay.Position = new Vector2(0.7f, 0.6f); this.drawToScreen.Add(this.rgbmTextureDisplay); this.drawToScreen.Add(this.rgbmTextureAlphaDisplay); this.drawToScreen.Add(this.bloomTextureDisplay); //setup the render config this.configEditor = new RenderConfigEditor(this.Content); this.drawToScreen.Add(configEditor); this.UpdateManager.Add(configEditor); //add a statistics overlay. drawStats = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); drawToScreen.Add(drawStats); }
protected override void Initialise() { //Xen.Ex provides a very useful Camera3D called 'FirstPersonControlledCamera3D'. //This camera uses player input to act as a simple first-person style flythrough camera Xen.Camera.FirstPersonControlledCamera3D camera = null; //it uses player input, so the UpdateManager must be passed in camera = new Xen.Camera.FirstPersonControlledCamera3D(this.UpdateManager); //in this case, we want the z-axis to be the up/down axis (otherwise it's the Y-axis) camera.ZAxisUp = true; //also it's default is a bit too fast moving camera.MovementSensitivity *= 0.1f; camera.LookAt(new Vector3(1, 0, 0), new Vector3(), new Vector3(0, 0, 1)); this.camera = camera; //create the draw target. drawToScreen = new DrawTargetScreen(camera); //create a large number of actor instance from tutorial 10.. for (int n = 0; n <= 16; n++) { //create in a half circle float angle = (n / 16.0f) * MathHelper.Pi; var position = new Vector3((float)Math.Sin(angle), (float)Math.Cos(angle), 0); //not too close together position *= 10; drawToScreen.Add(new Tutorial_10.Actor(this.Content, position)); } //this element will display the camera position positionDisplay = new TextElement(); //TextElement (unlike other Elements) defaults to Top Left alignment //So, in order to bring it closer to the centre of the screen (due to potential overscan) //it's position needs to be set 'right' and 'down' from 'top left' //(this is just an example, see XNA docs for correct overscan compensation behaviour) positionDisplay.Position = new Vector2(40, -40); //offset from top left corner alignment //add it to the screen drawToScreen.Add(positionDisplay); var sizeInPixels = new Vector2(400, 200); //create the main block of yellow text this.yellowElement = new TextElementRect(sizeInPixels); this.yellowElement.Colour = Color.Yellow; //first line of text... this will have a flashing 2D element embedded string embeddedText = @"This is a text box with a large amount of custom text! It also includes an embedded 2D element: , which is a 16x16 SolidColourElement"; uint insertAtIndex = 96; // Hard coded to insert a 2D element at character index 96 which is about here: ^ //add a bunch of text... this.yellowElement.Text.AppendLine(embeddedText); this.yellowElement.Text.AppendLine(); this.yellowElement.Text.AppendLine(@"This class is:"); this.yellowElement.Text.AppendLine(this.GetType().FullName); this.yellowElement.Text.AppendLine(@"It is located in assembly:"); this.yellowElement.Text.AppendLine(this.GetType().Assembly.FullName); this.yellowElement.Text.AppendLine(); //add an embedded 2D element within the text //create it.. this.embeddedElement = new SolidColourElement(Color.Red, new Vector2(16, 16)); // quite small this.embeddedElement.AlphaBlendState = AlphaBlendState.Alpha; //add it. this.yellowElement.AddInline(this.embeddedElement, insertAtIndex); #if XBOX360 this.yellowElement.Text.AppendLine(@"Press and hold both thumbsticks to show the debug overlay"); #else this.yellowElement.Text.AppendLine(@"Press F12 to show the debug overlay"); #endif //align the element rectangle to the bottom centre of the screen this.yellowElement.VerticalAlignment = VerticalAlignment.Bottom; this.yellowElement.HorizontalAlignment = HorizontalAlignment.Centre; //centre align the text this.yellowElement.TextHorizontalAlignment = TextHorizontalAlignment.Centre; //centre the text in the middle of the 400x200 area of the element rectangle this.yellowElement.TextVerticalAlignment = VerticalAlignment.Centre; //add it to the screen drawToScreen.Add(yellowElement); //create the statistics display //this class will query the DrawState for the previous frames DrawStatistics structure. //this structure provides a large number of statistics for the drawn frame. //The DrawStatisticsDisplay displays some of the more important statistics. It will also //display thread activity on the xbox. //DrawStatistics are only available in DEBUG xen builds //They can be accessed at runtime with DrawState GetPreviousFrameStatistics() //at runtime, pressing 'F12' will toggle the overlay (or holding both thumbsticks on x360) this.statisticsOverlay = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); //then add it to the screen drawToScreen.Add(statisticsOverlay); }
protected override void Initialise() { Camera3D camera = new Xen.Camera.FirstPersonControlledCamera3D(this.UpdateManager, Vector3.Zero,true); //create the draw target. drawToScreen = new DrawTargetScreen(camera); drawToScreen.ClearBuffer.ClearColour = Color.CornflowerBlue; //NEW CODE //create a BatchModel, this class stores the ModelData and will draw BatchModelInstances this.batchModel = new BatchModel(); //this.batchModel.ShaderProvider = new SimpleShaderProvider<Tutorial_16.Shader.Tutorial16>(); //NEW CODE //create a large number of actors (1600) for (float x = -20; x < 20; x++) for (float y = -20; y < 20; y++) { drawToScreen.Add(new Actor(this.batchModel, new Vector3(x * 5, y * 5, -5))); } //this is the most important bit... //always add the BatchModel itself to the draw target, //this should be added *after* all BatchModelInstances have been added //Note: each time a BatchModelInstance is drawn, it will store it's world matrix in the BatchModel //If the BatchModel is not drawn, the buffer storing these matrices will not be emptied, and will //eventually throw an OutOfMemoryException exception. this.drawToScreen.Add(batchModel); statistics = new Xen.Ex.Graphics2D.Statistics.DrawStatisticsDisplay(this.UpdateManager); this.drawToScreen.Add(statistics); }