private void texture_Disposing(object sender, EventArgs e) { if ((sender as Texture) == null) { return; } for (int i = 0; i < _packedTextures.Count; ++i) { PackedTexture bigOne = _packedTextures[i]; if (bigOne.texture == (Texture)sender) { if (bigOne.textureNo >= 0) { Log.Info("TexturePacker: disposing texture:{0}", bigOne.textureNo); DXNative.FontEngineRemoveTexture(bigOne.textureNo); if (Disposing != null) { Disposing(this, bigOne.textureNo); } } bigOne.texture = null; bigOne.textureNo = -1; return; } } }
/// <inheritdoc/> public void DrawBillboard(ref BillboardArgs billboard, PackedTexture texture) { int index, dummy; _renderBatch.Submit(PrimitiveType.TriangleList, 4, 6, out index, out dummy); OnDrawBillboard(ref billboard, texture, _renderBatch.Vertices, index); }
/// <inheritdoc/> public void DrawRibbon(ref RibbonArgs p0, ref RibbonArgs p1, PackedTexture texture) { int index, dummy; _renderBatch.Submit(PrimitiveType.TriangleList, 4, 6, out index, out dummy); OnDrawRibbon(ref p0, ref p1, texture, _renderBatch.Vertices, index); }
/// <inheritdoc/> protected override void CloneCore(Sprite source) { // Clone Sprite properties. base.CloneCore(source); // Clone ImageSprite properties. var sourceTyped = (ImageSprite)source; Texture = sourceTyped.Texture; }
// Each Texture2D gets a unique ID, which is used for state sorting. // The ID is assigned during BatchJobs() and reset during ProcessJobs(). private uint GetTextureId(PackedTexture texture) { if (texture == null) { return(0); // _defaultTexture will be used. } if (texture.TextureAtlasEx.Id == 0) { _textureCount++; texture.TextureAtlasEx.Id = _textureCount; } return(texture.TextureAtlasEx.Id); }
protected override void OnDrawRibbon(ref RibbonArgs p0, ref RibbonArgs p1, PackedTexture texture, BillboardVertex[] vertices, int index) { // p0 and p1 specify a segment of a particle ribbon. // --+--------------+-- // p0 p1 // --+--------------+-- // Bottom left vertex var v = new BillboardVertex(); v.Position = p0.Position; v.Axis = p0.Axis; v.Color3F = p0.Color; v.Alpha = p0.Alpha; v.TextureCoordinate = new Vector2F(p0.TextureCoordinateU, 1); v.Size = new Vector2F(p0.Size); v.Softness = p0.Softness; v.ReferenceAlpha = p0.ReferenceAlpha; v.AnimationTime = p0.AnimationTime; v.BlendMode = p0.BlendMode; v.Texture = texture; vertices[index] = v; index++; // Top left vertex v.TextureCoordinate.Y = 0; vertices[index] = v; index++; // Top right vertex v.Position = p1.Position; v.Axis = p1.Axis; v.Color3F = p1.Color; v.Alpha = p1.Alpha; v.TextureCoordinate = new Vector2F(p1.TextureCoordinateU, 0); v.Size = new Vector2F(p1.Size); v.Softness = p1.Softness; v.ReferenceAlpha = p1.ReferenceAlpha; v.AnimationTime = p1.AnimationTime; v.BlendMode = p1.BlendMode; vertices[index] = v; index++; // Bottom right vertex v.TextureCoordinate.Y = 1; vertices[index] = v; }
private void InitializeBillboards(IGraphicsService graphicsService) { _debugTexture = new PackedTexture(graphicsService.GetDefaultTexture2DWhite()); var graphicsDevice = GraphicsService.GraphicsDevice; _hiDef = (graphicsDevice.GraphicsProfile == GraphicsProfile.HiDef); if (_hiDef) { // ----- HiDef profile _billboardEffect = GraphicsService.Content.Load <Effect>("DigitalRune/Billboard"); _parameterView = _billboardEffect.Parameters["View"]; _parameterViewInverse = _billboardEffect.Parameters["ViewInverse"]; _parameterViewProjection = _billboardEffect.Parameters["ViewProjection"]; _parameterProjection = _billboardEffect.Parameters["Projection"]; _parameterCameraPosition = _billboardEffect.Parameters["CameraPosition"]; _parameterViewportSize = _billboardEffect.Parameters["ViewportSize"]; _parameterDepthBuffer = _billboardEffect.Parameters["DepthBuffer"]; _parameterCameraNear = _billboardEffect.Parameters["CameraNear"]; _parameterCameraFar = _billboardEffect.Parameters["CameraFar"]; _parameterTexture = _billboardEffect.Parameters["Texture"]; _techniqueHardLinear = _billboardEffect.Techniques["HardLinear"]; _techniqueHardGamma = _billboardEffect.Techniques["HardGamma"]; _techniqueSoftLinear = _billboardEffect.Techniques["SoftLinear"]; _techniqueSoftGamma = _billboardEffect.Techniques["SoftGamma"]; _billboardBatch = new BillboardBatchHiDef(graphicsDevice, BufferSize); } else { // ----- Reach profile _billboardEffect = new BasicEffect(graphicsDevice) { FogEnabled = false, LightingEnabled = false, TextureEnabled = true, VertexColorEnabled = true, World = Matrix.Identity, }; _billboardBatch = new BillboardBatchReach(graphicsDevice, BufferSize); } }
private void LoadPackedGraphics(int index) { // return ; PackedTexture bigOne = _packedTextures[index]; const Format useFormat = Format.A8R8G8B8; //if (IsCompressedTextureFormatOk(Format.Dxt5)) //{ // Log.Debug("TexturePacker: Using DXT5 texture format"); // useFormat = Format.Dxt5; //} if (bigOne.texture == null) { bigOne.textureNo = -1; string fileName = String.Format(@"{0}\packedgfx2{1}.png", GUIGraphicsContext.SkinCacheFolder, index); var info2 = new ImageInformation(); Texture tex = TextureLoader.FromFile(GUIGraphicsContext.DX9Device, fileName, 0, 0, //width/height 1, //mipslevels 0, //Usage.Dynamic, useFormat, GUIGraphicsContext.GetTexturePoolType(), Filter.None, Filter.None, 0, ref info2); bigOne.texture = tex; bigOne.texture.Disposing -= TextureDisposing; bigOne.texture.Disposing += TextureDisposing; Log.Info("TexturePacker: Loaded {0} texture:{1}x{2} miplevels:{3}", fileName, info2.Width, info2.Height, tex.LevelCount); } }
protected override void OnDrawBillboard(ref BillboardArgs b, PackedTexture texture, BillboardVertex[] vertices, int index) { // Bottom left vertex var v = new BillboardVertex(); v.Position = b.Position; v.Normal = b.Normal; v.Axis = b.Axis; v.Color3F = b.Color; v.Alpha = b.Alpha; v.TextureCoordinate = new Vector2F(0, 1); v.Orientation = b.Orientation; v.Angle = b.Angle; v.Size = b.Size; v.Softness = b.Softness; v.ReferenceAlpha = b.ReferenceAlpha; v.AnimationTime = b.AnimationTime; v.BlendMode = b.BlendMode; v.Texture = texture; vertices[index] = v; index++; // Top left vertex v.TextureCoordinate.Y = 0; vertices[index] = v; index++; // Top right vertex v.TextureCoordinate.X = 1; vertices[index] = v; index++; // Bottom right vertex v.TextureCoordinate.Y = 1; vertices[index] = v; }
private readonly LensFlareRenderer _lensFlareRenderer; // Handles LensFlareNodes. public LensFlareSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService) { RenderCallback = Render, }; GraphicsService.Screens.Insert(0, delegateGraphicsScreen); // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); GameObjectService.Objects.Add(_cameraObject); // Create a new empty scene. _scene = new Scene(); // Add the camera node to the scene. _scene.Children.Add(_cameraObject.CameraNode); // Add a few models to the scene. var ground = ContentManager.Load <ModelNode>("Ground/Ground").Clone(); _scene.Children.Add(ground); var box = ContentManager.Load <ModelNode>("MetalGrateBox/MetalGrateBox").Clone(); box.PoseLocal = new Pose(new Vector3(0.5f, 0.5f, 0.5f), Matrix.CreateRotationY(0.1f)); _scene.Children.Add(box); // Add some lights to the scene which have the same properties as the lights // of BasicEffect.EnableDefaultLighting(). SceneSample.InitializeDefaultXnaLights(_scene); // Add a lens flare for the sun light. var lensFlare = new LensFlare(true); // The sun is a directional light source. lensFlare.Name = "Sun Flare"; // The Size determines the screen size of the lens flare elements. The value // is relative to the viewport height. lensFlare.Size = 0.28f; // 0.28 * viewport height // The QuerySize of a directional light is the estimated size relative to the // viewport. This value is used in the hardware occlusion query, which determines // whether the lens flare is visible. lensFlare.QuerySize = 0.18f; // 0.18 * viewport height // All lens flare elements are packed into one texture ("texture atlas"). // The PackedTexture identifies an element within the texture atlas. // See file Media/LensFlare/LensFlares.png. // (Credits: The sun lens flare was copied from the XNA racing game - http://exdream.com/XnaRacingGame/.) var lensFlareTexture = ContentManager.Load <Texture2D>("LensFlare/LensFlares"); var circleTexture = new PackedTexture("Circle", lensFlareTexture, new Vector2F(0, 0), new Vector2F(0.25f, 0.5f)); var glowTexture = new PackedTexture("Glow", lensFlareTexture, new Vector2F(0.25f, 0), new Vector2F(0.25f, 0.5f)); var ringTexture = new PackedTexture("Ring", lensFlareTexture, new Vector2F(0.5f, 0), new Vector2F(0.25f, 0.5f)); var haloTexture = new PackedTexture("Halo", lensFlareTexture, new Vector2F(0.75f, 0), new Vector2F(0.25f, 0.5f)); var sunTexture = new PackedTexture("Sun", lensFlareTexture, new Vector2F(0, 0.5f), new Vector2F(0.25f, 0.5f)); var streaksTexture = new PackedTexture("Streaks", lensFlareTexture, new Vector2F(0.25f, 0.5f), new Vector2F(0.25f, 0.5f)); var flareTexture = new PackedTexture("Flare", lensFlareTexture, new Vector2F(0.5f, 0.5f), new Vector2F(0.25f, 0.5f)); // Add a few elements (circles, glow, rings, halos, streaks, ...) to the lens flare. lensFlare.Elements.Add(new LensFlareElement(-0.2f, 0.55f, 0.0f, new Color(175, 175, 255, 20), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 0.9f, 0.0f, new Color(255, 255, 255, 255), new Vector2F(0.5f, 0.5f), sunTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 1.8f, 0.0f, new Color(255, 255, 255, 128), new Vector2F(0.5f, 0.5f), streaksTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 2.6f, 0.0f, new Color(255, 255, 200, 64), new Vector2F(0.5f, 0.5f), glowTexture)); lensFlare.Elements.Add(new LensFlareElement(0.5f, 0.12f, 0.0f, new Color(60, 60, 180, 35), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.55f, 0.46f, 0.0f, new Color(100, 100, 200, 60), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.6f, 0.17f, 0.0f, new Color(120, 120, 220, 40), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.85f, 0.2f, 0.0f, new Color(60, 60, 255, 100), new Vector2F(0.5f, 0.5f), ringTexture)); lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.2f, 0.0f, new Color(255, 60, 60, 130), new Vector2F(0.5f, 0.5f), flareTexture)); lensFlare.Elements.Add(new LensFlareElement(0.15f, 0.15f, 0.0f, new Color(255, 60, 60, 90), new Vector2F(0.5f, 0.5f), flareTexture)); lensFlare.Elements.Add(new LensFlareElement(1.3f, 0.6f, 0.0f, new Color(60, 60, 255, 180), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.4f, 0.2f, 0.0f, new Color(220, 80, 80, 98), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.1f, 0.0f, new Color(220, 80, 80, 85), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(1.6f, 0.5f, 0.0f, new Color(60, 60, 255, 80), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.8f, 0.3f, 0.0f, new Color(90, 60, 255, 110), new Vector2F(0.5f, 0.5f), ringTexture)); lensFlare.Elements.Add(new LensFlareElement(1.95f, 0.5f, 0.0f, new Color(60, 60, 255, 120), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(2.0f, 0.15f, 0.0f, new Color(60, 60, 255, 85), new Vector2F(0.5f, 0.5f), circleTexture)); // The scene node "KeyLight" (defined in SceneSample.InitializeDefaultXnaLights()) // is the main directional light source. var keyLightNode = _scene.GetDescendants().First(n => n.Name == "KeyLight"); // Let's attach the lens flare to the "KeyLight" node. // (Note: It is not necessary to attach a lens flare to a light node. Lens flares // can be added anywhere within the scene. But attaching the lens flare to the // light node ensures that the lens flare always has the same position and direction // as the light source.) var lensFlareNode = new LensFlareNode(lensFlare); keyLightNode.Children = new SceneNodeCollection(); keyLightNode.Children.Add(lensFlareNode); // Add a second lens flare. // The previous lens flare was a caused by a directional light source (distance = infinite). // This time we add a local lens flare. lensFlare = new LensFlare(false); lensFlare.Name = "Anamorphic Flare"; lensFlare.Size = 0.3f; // 0.3 * viewport height // The QuerySize of a local lens flare is estimated size of the light source // in world space. lensFlare.QuerySize = 0.2f; // 0.2 meters // Add some elements (glow, horizontal streaks, ...) to the lens flare effect. var anamorphicFlareTexture = ContentManager.Load <Texture2D>("LensFlare/AnamorphicFlare"); flareTexture = new PackedTexture("AnamorphicFlare", anamorphicFlareTexture, new Vector2F(0, 0), new Vector2F(1.0f, 87f / 256f)); var flare1Texture = new PackedTexture("Flare0", anamorphicFlareTexture, new Vector2F(227f / 512f, 88f / 256f), new Vector2F(285f / 512f, 15f / 256f)); var flare2Texture = new PackedTexture("Flare1", anamorphicFlareTexture, new Vector2F(0, 87f / 256f), new Vector2F(226f / 512f, 168f / 256f)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 0.8f, 0.0f, new Color(255, 255, 255, 255), new Vector2F(0.5f, 0.5f), flareTexture)); lensFlare.Elements.Add(new LensFlareElement(1.0f, new Vector2F(0.6f, 0.5f), 0.0f, new Color(172, 172, 255, 32), new Vector2F(0.5f, 0.5f), flare1Texture)); lensFlare.Elements.Add(new LensFlareElement(1.5f, 1.2f, float.NaN, new Color(200, 200, 255, 24), new Vector2F(0.5f, 0.2f), flare2Texture)); lensFlare.Elements.Add(new LensFlareElement(2.0f, 2.0f, float.NaN, new Color(172, 172, 255, 48), new Vector2F(0.5f, 0.2f), flare2Texture)); // Position the lens flare near the origin. lensFlareNode = new LensFlareNode(lensFlare); lensFlareNode.PoseWorld = new Pose(new Vector3(-0.5f, 1, 0)); _scene.Children.Add(lensFlareNode); // In this example we need two renderers: // The MeshRenderer handles MeshNodes. _meshRenderer = new MeshRenderer(); // The LensFlareRenderer handles LensFlareNodes. _lensFlareRenderer = new LensFlareRenderer(GraphicsService); }
public BillboardSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService) { RenderCallback = Render, }; GraphicsService.Screens.Insert(0, delegateGraphicsScreen); // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); GameObjectService.Objects.Add(_cameraObject); // In this example we need three renderers: // The MeshRenderer handles MeshNodes. _meshRenderer = new MeshRenderer(); // The BillboardRenderer handles BillboardNodes and ParticleSystemNodes. _billboardRenderer = new BillboardRenderer(GraphicsService, 2048); // The DebugRenderer is used to draw text. var spriteFont = UIContentManager.Load <SpriteFont>("UI Themes/BlendBlue/Default"); _debugRenderer = new DebugRenderer(GraphicsService, spriteFont); // Create a new empty scene. _scene = new Scene(); // Add the camera node to the scene. _scene.Children.Add(_cameraObject.CameraNode); // Add a few models to the scene. var sandbox = ContentManager.Load <ModelNode>("Sandbox/Sandbox").Clone(); _scene.Children.Add(sandbox); // Add some lights to the scene which have the same properties as the lights // of BasicEffect.EnableDefaultLighting(). SceneSample.InitializeDefaultXnaLights(_scene); var texture = new PackedTexture(ContentManager.Load <Texture2D>("Billboard/BillboardReference")); // ----- View plane-aligned billboards with variations. // View plane-aligned billboards are rendered parallel to the screen. // The up-axis of the BillboardNode determines the up direction of the // billboard. var pose0 = new Pose(new Vector3(-9, 1.0f, 1.5f)); var pose1 = pose0; var billboard = new ImageBillboard(texture); var billboardNode = new BillboardNode(billboard); billboardNode.Name = "View plane-aligned\nVarying color\nVarying alpha"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; billboardNode.Color = new Vector3(1, 0, 0); billboardNode.Alpha = 0.9f; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; billboardNode.Color = new Vector3(0, 1, 0); billboardNode.Alpha = 0.7f; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; billboardNode.Color = new Vector3(0, 0, 1); billboardNode.Alpha = 0.3f; _scene.Children.Add(billboardNode); // ----- View plane-aligned billboards with different blend modes // blend mode = 0 ... additive blend // blend mode = 1 ... alpha blend pose0.Position.X += 2; pose1 = pose0; billboard = new ImageBillboard(texture); billboard.BlendMode = 0.0f; billboardNode = new BillboardNode(billboard); billboardNode.Name = "View plane-aligned\nVarying blend mode"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboard = new ImageBillboard(texture); billboard.BlendMode = 0.333f; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboard = new ImageBillboard(texture); billboard.BlendMode = 0.667f; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboard = new ImageBillboard(texture); billboard.BlendMode = 1.0f; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); // ----- View plane-aligned billboards with alpha test pose0.Position.X += 2; pose1 = pose0; billboard = new ImageBillboard(texture); billboard.AlphaTest = 0.9f; billboardNode = new BillboardNode(billboard); billboardNode.Name = "View plane-aligned\nVarying reference alpha"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboard = new ImageBillboard(texture); billboard.AlphaTest = 0.667f; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboard = new ImageBillboard(texture); billboard.AlphaTest = 0.333f; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboard = new ImageBillboard(texture); billboard.AlphaTest = 0.0f; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); // ----- View plane-aligned billboards with different scale and rotation pose0.Position.X += 2; pose1 = pose0; billboard = new ImageBillboard(texture); billboard.Orientation = BillboardOrientation.ViewPlaneAligned; billboardNode = new BillboardNode(billboard); billboardNode.Name = "View plane-aligned\nVarying scale\nVarying rotation"; billboardNode.PoseWorld = pose1; billboardNode.ScaleLocal = new Vector3(0.4f); _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = billboardNode.Clone(); billboardNode.Name = null; billboardNode.PoseWorld = pose1 * new Pose(Matrix.CreateRotationZ(MathHelper.ToRadians(-15))); billboardNode.ScaleLocal = new Vector3(0.6f); _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = billboardNode.Clone(); billboardNode.Name = null; billboardNode.PoseWorld = pose1 * new Pose(Matrix.CreateRotationZ(MathHelper.ToRadians(-30))); billboardNode.ScaleLocal = new Vector3(0.8f); _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = billboardNode.Clone(); billboardNode.Name = null; billboardNode.PoseWorld = pose1 * new Pose(Matrix.CreateRotationZ(MathHelper.ToRadians(-45))); billboardNode.ScaleLocal = new Vector3(1.0f); _scene.Children.Add(billboardNode); // ----- Viewpoint-oriented billboards // Viewpoint-orientated billboards always face the player. (The face normal // points directly to the camera.) pose0.Position.X += 2; pose1 = pose0; billboard = new ImageBillboard(texture); billboard.Orientation = BillboardOrientation.ViewpointOriented; billboardNode = new BillboardNode(billboard); billboardNode.Name = "Viewpoint-oriented"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); // ----- Screen-aligned billboards // View plane-aligned billboards and screen-aligned billboards are similar. The // billboards are rendered parallel to the screen. The orientation can be changed // by rotating the BillboardNode. The difference is that the orientation of view // plane-aligned billboards is relative to world space and the orientation of // screen-aligned billboards is relative to view space. // Screen-aligned billboards are, for example, used for text label. pose0.Position.X += 2; pose1 = pose0; billboard = new ImageBillboard(texture); billboard.Orientation = BillboardOrientation.ScreenAligned; billboardNode = new BillboardNode(billboard); billboardNode.Name = "Screen-aligned"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); // ----- Axial, view plane-aligned billboards pose0.Position.X += 2; pose1 = pose0; billboard = new ImageBillboard(texture); billboard.Orientation = BillboardOrientation.AxialViewPlaneAligned; billboardNode = new BillboardNode(billboard); billboardNode.Name = "Axial, view plane-aligned"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = billboardNode.Clone(); billboardNode.Name = null; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); // ----- Axial, viewpoint-oriented billboards pose0.Position.X += 2; pose1 = pose0; billboard = new ImageBillboard(texture); billboard.Orientation = BillboardOrientation.AxialViewpointOriented; billboardNode = new BillboardNode(billboard); billboardNode.Name = "Axial, viewpoint-oriented"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); // ----- World-oriented billboards // World-oriented billboards have a fixed orientation in world space. The // orientation is determine by the BillboardNode. pose0.Position.X += 2; pose1 = pose0; pose1.Orientation *= Matrix.CreateRotationY(0.2f); billboard = new ImageBillboard(texture); billboard.Orientation = BillboardOrientation.WorldOriented; billboardNode = new BillboardNode(billboard); billboardNode.Name = "World-oriented"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; pose1.Orientation *= Matrix.CreateRotationY(0.2f); billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1 * new Pose(Matrix.CreateRotationZ(MathHelper.ToRadians(15))); _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; pose1.Orientation *= Matrix.CreateRotationY(0.2f); billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1 * new Pose(Matrix.CreateRotationZ(MathHelper.ToRadians(30))); _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; pose1.Orientation *= Matrix.CreateRotationY(0.2f); billboardNode = new BillboardNode(billboard); billboardNode.PoseWorld = pose1 * new Pose(Matrix.CreateRotationZ(MathHelper.ToRadians(45))); _scene.Children.Add(billboardNode); // ----- Animated billboards // DigitalRune Graphics supports "texture atlases". I.e. textures can be packed // together into a single, larger texture file. A PackedTexture can describe a // single texture packed into a texture atlas or a tile set packed into a // texture atlas. In this example the "beeWingFlap" is a set of three tiles. // Tile sets can be used for sprite animations. (The animation is set below in // Update().) pose0.Position.X += 2; pose1 = pose0; texture = new PackedTexture("Bee", ContentManager.Load <Texture2D>("Particles/beeWingFlap"), Vector2F.Zero, Vector2F.One, 3, 1); _animatedBillboard = new ImageBillboard(texture); billboardNode = new BillboardNode(_animatedBillboard); billboardNode.Name = "Animated billboards"; billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(_animatedBillboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); pose1.Position.Z -= 1; billboardNode = new BillboardNode(_animatedBillboard); billboardNode.PoseWorld = pose1; _scene.Children.Add(billboardNode); // Use DebugRenderer to draw node names above billboard nodes. foreach (var node in _scene.GetDescendants().OfType <BillboardNode>()) { _debugRenderer.DrawText(node.Name, node.PoseWorld.Position + new Vector3(0, 1, 0), new Vector2F(0.5f), Color.Yellow, false); } }
private static void ResetTextureId(PackedTexture texture) { texture.TextureAtlasEx.Id = 0; }
public void PackSkinGraphics(string skinName) { Cleanup(); if (LoadPackedSkin(skinName)) { return; } _packedTextures = new List <PackedTexture>(); List <string> files = new List <string>(); using (Settings xmlreader = new MPSettings()) { if (xmlreader.GetValueAsBool("debug", "packSkinGfx", true)) { string[] skinFiles = Directory.GetFiles(String.Format(@"{0}\media", skinName), "*.png"); files.AddRange(skinFiles); } // workaround for uncommon rendering implementation of volume osd - it won't show up without packedtextures else { string[] skinFiles = Directory.GetFiles(String.Format(@"{0}\media", skinName), "volume*.png"); string[] forcedCacheFiles = Directory.GetFiles(String.Format(@"{0}\media", skinName), "cached*.png"); files.Add(String.Format(@"{0}\media\Thumb_Mask.png", skinName)); files.AddRange(skinFiles); files.AddRange(forcedCacheFiles); } if (xmlreader.GetValueAsBool("debug", "packLogoGfx", true)) { string[] tvLogos = Directory.GetFiles(Config.GetSubFolder(Config.Dir.Thumbs, @"tv\logos"), "*.png", SearchOption.AllDirectories); string[] radioLogos = Directory.GetFiles(Config.GetSubFolder(Config.Dir.Thumbs, "Radio"), "*.png", SearchOption.AllDirectories); files.AddRange(tvLogos); files.AddRange(radioLogos); } if (xmlreader.GetValueAsBool("debug", "packPluginGfx", true)) { string[] weatherFiles = Directory.GetFiles(String.Format(@"{0}\media\weather", skinName), "*.png"); string[] tetrisFiles = Directory.GetFiles(String.Format(@"{0}\media\tetris", skinName), "*.png"); files.AddRange(weatherFiles); files.AddRange(tetrisFiles); } } // Determine maximum texture dimensions try { Caps d3dcaps = GUIGraphicsContext.DX9Device.DeviceCaps; _maxTextureWidth = d3dcaps.MaxTextureWidth; _maxTextureHeight = d3dcaps.MaxTextureHeight; Log.Info("TexturePacker: D3D device does support {0}x{1} textures", _maxTextureWidth, _maxTextureHeight); } catch (Exception) { _maxTextureWidth = 2048; _maxTextureHeight = 2048; } if (_maxTextureWidth > MAXTEXTUREDIMENSION) { _maxTextureWidth = MAXTEXTUREDIMENSION; } if (_maxTextureHeight > MAXTEXTUREDIMENSION) { _maxTextureHeight = MAXTEXTUREDIMENSION; } Log.Info("TexturePacker: using {0}x{1} as packed textures limit", _maxTextureWidth, _maxTextureHeight); Log.Info("TexturePacker: using {0}x{1} as single texture limit", _maxTextureWidth / 2, _maxTextureHeight / 2); while (true) { bool ImagesLeft = false; PackedTexture bigOne = new PackedTexture(); bigOne.root = new PackedTextureNode(); bigOne.texture = null; bigOne.textureNo = -1; using (Bitmap rootImage = new Bitmap(_maxTextureWidth, _maxTextureHeight)) { bigOne.root.Rect = new Rectangle(0, 0, _maxTextureWidth, _maxTextureHeight); for (int i = 0; i < files.Count; ++i) { if (files[i] == null) { continue; } files[i] = files[i].ToLowerInvariant(); if (files[i] != string.Empty) { // Ignore files not needed for MP if (files[i].IndexOf("preview.") >= 0) { files[i] = string.Empty; continue; } bool dontAdd; if (AddBitmap(bigOne.root, rootImage, files[i], out dontAdd)) { files[i] = string.Empty; } else { if (dontAdd) { files[i] = string.Empty; } else { ImagesLeft = true; } } } } if (!Directory.Exists(GUIGraphicsContext.SkinCacheFolder)) { Directory.CreateDirectory(GUIGraphicsContext.SkinCacheFolder); } string fileName = String.Format(@"{0}\packedgfx2{1}.png", GUIGraphicsContext.SkinCacheFolder, _packedTextures.Count); rootImage.Save(fileName, ImageFormat.Png); Log.Debug("TexturePacker: Cache root {0} filled", fileName); } _packedTextures.Add(bigOne); if (!ImagesLeft) { break; } } SavePackedSkin(skinName); }
public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order) { ThrowIfDisposed(); if (nodes == null) { throw new ArgumentNullException("nodes"); } if (context == null) { throw new ArgumentNullException("context"); } int numberOfNodes = nodes.Count; if (nodes.Count == 0) { return; } context.Validate(_effect); var originalRenderTarget = context.RenderTarget; var originalViewport = context.Viewport; var graphicsDevice = context.GraphicsService.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.BlendState = BlendState.Opaque; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.None; int frame = context.Frame; float deltaTime = (float)context.DeltaTime.TotalSeconds; for (int nodeIndex = 0; nodeIndex < numberOfNodes; nodeIndex++) { var cloudNode = nodes[nodeIndex] as CloudLayerNode; if (cloudNode == null) { continue; } var cloudMap = cloudNode.CloudMap as LayeredCloudMap; if (cloudMap == null) { continue; } // We update the cloud map only once per frame. if (cloudMap.LastFrame == frame) { continue; } cloudMap.LastFrame = frame; var layers = cloudMap.Layers; var animationTimes = cloudMap.AnimationTimes; var sources = cloudMap.SourceLayers; var targets = cloudMap.TargetLayers; var renderTargets = cloudMap.LayerTextures; // Animate the cloud map layers. for (int i = 0; i < LayeredCloudMap.NumberOfTextures; i++) { if (layers[i] == null || layers[i].Texture != null) { continue; } if (cloudMap.Random == null) { cloudMap.Random = new Random(cloudMap.Seed); } // Make sure there is a user-defined texture or data for procedural textures. if (sources[i] == null) { // Each octave is 128 x 128 (= 1 / 4 of the 512 * 512 noise texture). sources[i] = new PackedTexture(null, _noiseTexture, cloudMap.Random.NextVector2F(0, 1), new Vector2F(0.25f)); targets[i] = new PackedTexture(null, _noiseTexture, cloudMap.Random.NextVector2F(0, 1), new Vector2F(0.25f)); renderTargets[i] = new RenderTarget2D(graphicsDevice, 128, 128, false, SurfaceFormat.Alpha8, DepthFormat.None); } // Update animation time. animationTimes[i] += deltaTime * layers[i].AnimationSpeed; // Update source and target if animation time is beyond 1. if (animationTimes[i] > 1) { // Wrap animation time. animationTimes[i] = animationTimes[i] % 1; // Swap source and target. MathHelper.Swap(ref sources[i], ref targets[i]); // Set target to a new random part of the noise texture. targets[i].Offset = cloudMap.Random.NextVector2F(0, 1); } // Lerp source and target together to get the final noise texture. graphicsDevice.SetRenderTarget(renderTargets[i]); _parameterViewportSize.SetValue(new Vector2(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height)); _parameterTextures[0].SetValue(sources[i].TextureAtlas); _parameterTextures[1].SetValue(targets[i].TextureAtlas); _parameterTexture0Parameters.SetValue(new Vector4(sources[i].Scale.X, sources[i].Scale.Y, sources[i].Offset.X, sources[i].Offset.Y)); _parameterTexture1Parameters.SetValue(new Vector4(targets[i].Scale.X, targets[i].Scale.Y, targets[i].Offset.X, targets[i].Offset.Y)); _parameterLerp.SetValue(animationTimes[i]); _passLerp.Apply(); graphicsDevice.DrawFullScreenQuad(); } // Initialize the cloud map. if (cloudMap.Texture == null || cloudMap.Size != cloudMap.Texture.Width) { cloudMap.Texture.SafeDispose(); var cloudTexture = new RenderTarget2D( graphicsDevice, cloudMap.Size, cloudMap.Size, false, SurfaceFormat.Alpha8, DepthFormat.None); cloudMap.SetTexture(cloudTexture); } // Combine the layers. graphicsDevice.SetRenderTarget((RenderTarget2D)cloudMap.Texture); _parameterViewportSize.SetValue(new Vector2(cloudMap.Texture.Width, cloudMap.Texture.Height)); for (int i = 0; i < LayeredCloudMap.NumberOfTextures; i++) { var layer = layers[i] ?? EmptyLayer; _parameterTextures[i].SetValue(layer.Texture ?? renderTargets[i]); _parameterMatrices[i].SetValue((Matrix) new Matrix44F(layer.TextureMatrix, Vector3F.Zero)); _parameterDensities[i].SetValue(new Vector2(layer.DensityScale, layer.DensityOffset)); } _parameterCoverage.SetValue(cloudMap.Coverage); _parameterDensity.SetValue(cloudMap.Density); _passDensity.Apply(); graphicsDevice.DrawFullScreenQuad(); } savedRenderState.Restore(); graphicsDevice.SetRenderTarget(null); context.RenderTarget = originalRenderTarget; context.Viewport = originalViewport; }
public void Update(ParticleSystem particleSystem) { Particles.Clear(); var numberOfParticles = particleSystem.NumberOfActiveParticles; if (numberOfParticles == 0) { // Clear texture reference to allow garbage collection. // (Only relevant, if user switches texture.) Texture = null; return; } // Pose (relative to root particle system) var parent = particleSystem.Parent; if (parent == null) { Pose = Pose.Identity; } else { // Collect all poses except for the root particle system pose. Pose = particleSystem.Pose; while (parent.Parent != null) { Pose = parent.Pose * Pose; parent = parent.Parent; } } // ReferenceFrame ReferenceFrame = particleSystem.ReferenceFrame; // ----- Uniform particle parameters // Texture var packedTextureParameter = TextureParameter as IParticleParameter<PackedTexture>; if (packedTextureParameter != null) { Texture = packedTextureParameter.DefaultValue; } else { var textureParameter = TextureParameter as IParticleParameter<Texture2D>; if (textureParameter != null) { var texture = textureParameter.DefaultValue; if (texture != null) { if (Texture == null || Texture.TextureAtlas != texture) Texture = new PackedTexture(texture); } else { Texture = null; } } } // Particles are not rendered without a texture. if (Texture == null) return; float aspectRatio = 1.0f; if (Texture != null) { var texture = Texture.TextureAtlas; float textureAspectRatio = (float)texture.Width / texture.Height; Vector2F texCoordTopLeft = Texture.Offset; Vector2F texCoordBottomRight = Texture.Offset + (Texture.Scale / new Vector2F(Texture.NumberOfColumns, Texture.NumberOfRows)); aspectRatio = textureAspectRatio * (texCoordBottomRight.X - texCoordTopLeft.X) / (texCoordBottomRight.Y - texCoordTopLeft.Y); } // AlphaTest AlphaTest = (AlphaTestParameter != null) ? AlphaTestParameter.DefaultValue : 0.0f; // BillboardOrientation BillboardOrientation = (BillboardOrientationParameter != null) ? BillboardOrientationParameter.DefaultValue : BillboardOrientation.ViewPlaneAligned; // DrawOrder DrawOrder = (DrawOrderParameter != null) ? DrawOrderParameter.DefaultValue : 0; // IsDepthSorted IsDepthSorted = (IsDepthSortedParameter != null) ? IsDepthSortedParameter.DefaultValue : false; // Softness Softness = (SoftnessParameter != null) ? SoftnessParameter.DefaultValue : 0; if (Numeric.IsNaN(Softness)) Softness = -1; // ParticleType (particles vs. ribbons) IsRibbon = (TypeParameter != null) ? (TypeParameter.DefaultValue == ParticleType.Ribbon) : false; // StartsAtOrigin //StartsAtOrigin = (StartsAtOriginParameter != null) ? StartsAtOriginParameter.DefaultValue : false; // TextureTiling TextureTiling = (TextureTilingParameter != null) ? TextureTilingParameter.DefaultValue : 0; // ----- Varying particle parameters Particles.AddRange(numberOfParticles); // Values are set below. var targetArray = Particles.Array; // Determine default size of particles. If one dimension is missing, calculate the // missing value using the aspect ratio of the texture. Vector2F size = Vector2F.One; if (SizeParameter != null) size = new Vector2F(SizeParameter.DefaultValue); if (SizeXParameter != null) size.X = SizeXParameter.DefaultValue; if (SizeYParameter != null) size.Y = SizeYParameter.DefaultValue; if (SizeParameter == null && SizeXParameter != null && SizeYParameter == null) size.Y = size.X / aspectRatio; if (SizeParameter == null && SizeXParameter == null && SizeYParameter != null) size.X = size.Y * aspectRatio; // Initialize particles with default values. var defaultParticle = new Particle { Position = (PositionParameter != null) ? PositionParameter.DefaultValue : new Vector3F(), Normal = (NormalParameter != null) ? NormalParameter.DefaultValue : Vector3F.UnitZ, Axis = (AxisParameter != null) ? AxisParameter.DefaultValue : Vector3F.Up, Size = size, Angle = (AngleParameter != null) ? AngleParameter.DefaultValue : 0.0f, Color = (ColorParameter != null) ? ColorParameter.DefaultValue : Vector3F.One, Alpha = (AlphaParameter != null) ? AlphaParameter.DefaultValue : 1.0f, BlendMode = (BlendModeParameter != null) ? BlendModeParameter.DefaultValue : 1.0f, // AnimationTime is initialized with NormalizedAge below. }; for (int i = 0; i < numberOfParticles; i++) targetArray[i] = defaultParticle; int startIndex = particleSystem.ParticleStartIndex; int totalCount = numberOfParticles; int count0 = totalCount; int endIndex0 = startIndex + count0; int endIndex1 = 0; if (endIndex0 > particleSystem.MaxNumberOfParticles) { count0 = particleSystem.MaxNumberOfParticles - startIndex; endIndex0 = particleSystem.MaxNumberOfParticles; endIndex1 = numberOfParticles - count0; } // NormalizedAge if (NormalizedAgeParameter != null && !NormalizedAgeParameter.IsUniform) { var sourceArray = NormalizedAgeParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].IsAlive = (sourceArray[sourceIndex] < 1.0f); targetArray[targetIndex].AnimationTime = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].IsAlive = (sourceArray[sourceIndex] < 1.0f); targetArray[targetIndex].AnimationTime = sourceArray[sourceIndex]; } } // Position if (PositionParameter != null && !PositionParameter.IsUniform) { var sourceArray = PositionParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Position = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Position = sourceArray[sourceIndex]; } // Normal if (NormalParameter != null && !NormalParameter.IsUniform) { var sourceArray = NormalParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Normal = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Normal = sourceArray[sourceIndex]; } // Axis if (AxisParameter != null && !AxisParameter.IsUniform) { var sourceArray = AxisParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Axis = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Axis = sourceArray[sourceIndex]; } // Size if (SizeParameter != null && !SizeParameter.IsUniform) { var sourceArray = SizeParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Size = new Vector2F(sourceArray[sourceIndex]); for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Size = new Vector2F(sourceArray[sourceIndex]); } if (SizeXParameter != null && !SizeXParameter.IsUniform) { var sourceArray = SizeXParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Size.X = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Size.X = sourceArray[sourceIndex]; } if (SizeYParameter != null && !SizeYParameter.IsUniform) { var sourceArray = SizeYParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Size.Y = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Size.Y = sourceArray[sourceIndex]; } if (SizeParameter == null && SizeXParameter != null && !SizeXParameter.IsUniform && SizeYParameter == null) { for (int i = 0; i < numberOfParticles; i++) targetArray[i].Size.Y = targetArray[i].Size.X / aspectRatio; } if (SizeParameter == null && SizeXParameter == null && SizeYParameter != null && !SizeYParameter.IsUniform) { for (int i = 0; i < numberOfParticles; i++) targetArray[i].Size.X = targetArray[i].Size.Y * aspectRatio; } // Angle if (AngleParameter != null && !AngleParameter.IsUniform) { var sourceArray = AngleParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Angle = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Angle = sourceArray[sourceIndex]; } // Color if (ColorParameter != null && !ColorParameter.IsUniform) { var sourceArray = ColorParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Color = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Color = sourceArray[sourceIndex]; } // Alpha if (AlphaParameter != null && !AlphaParameter.IsUniform) { var sourceArray = AlphaParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].Alpha = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].Alpha = sourceArray[sourceIndex]; } // AnimationTime if (AnimationTimeParameter != null) { // AnimationTime has been initialized with NormalizedAge for automatic animations. // But the "AnimationTime" parameter is set explicitly! if (AnimationTimeParameter.IsUniform) { float animationTime = AnimationTimeParameter.DefaultValue; for (int i = 0; i < numberOfParticles; i++) targetArray[i].AnimationTime = animationTime; } else { var sourceArray = AnimationTimeParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].AnimationTime = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].AnimationTime = sourceArray[sourceIndex]; } } // BlendMode if (BlendModeParameter != null && !BlendModeParameter.IsUniform) { var sourceArray = BlendModeParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) targetArray[targetIndex].BlendMode = sourceArray[sourceIndex]; for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) targetArray[targetIndex].BlendMode = sourceArray[sourceIndex]; } }
/// <summary> /// Initializes a new instance of the <see cref="ImageSprite"/> class with the specified /// texture. /// </summary> /// <param name="texture">The texture. (Can be <see langword="null"/>.)</param> public ImageSprite(PackedTexture texture) { Texture = texture; }
protected override void OnDrawRibbon(ref RibbonArgs p0, ref RibbonArgs p1, PackedTexture texture, VertexPositionColorTexture[] vertices, int index) { // p0 and p1 specify a segment of a particle ribbon. // --+--------------+-- // p0 p1 // --+--------------+-- #region ----- Handle texture information and size ----- float animationTime = p0.AnimationTime; Vector2F texCoordTopLeft = texture.GetTextureCoordinates(new Vector2F(p0.TextureCoordinateU, 0), animationTime); Vector2F texCoordBottomRight = texture.GetTextureCoordinates(new Vector2F(p1.TextureCoordinateU, 1), animationTime); // Negative sizes (mirroring) is not supported because this conflicts with the // texture tiling on ribbons. float size0 = Math.Abs(p0.Size) / 2; float size1 = Math.Abs(p1.Size) / 2; // Offset from particle center to upper edge. Vector3F up0; up0.X = p0.Axis.X * size0; up0.Y = p0.Axis.Y * size0; up0.Z = p0.Axis.Z * size0; Vector3F up1; up1.X = p1.Axis.X * size1; up1.Y = p1.Axis.Y * size1; up1.Z = p1.Axis.Z * size1; #endregion #region ----- Get Color ----- // Premultiply alpha. Vector4 color4 = new Vector4 { X = p0.Color.X * p0.Alpha, Y = p0.Color.Y * p0.Alpha, Z = p0.Color.Z * p0.Alpha, // Apply blend mode (0 = additive, 1 = alpha blend). W = p0.Alpha * p0.BlendMode }; var color0 = new Color(color4); color4 = new Vector4 { X = p1.Color.X * p1.Alpha, Y = p1.Color.Y * p1.Alpha, Z = p1.Color.Z * p1.Alpha, W = p1.Alpha * p1.BlendMode }; var color1 = new Color(color4); #endregion #region ----- Initializes vertices in vertex array ----- // Bottom left vertex vertices[index].Position.X = p0.Position.X - up0.X; vertices[index].Position.Y = p0.Position.Y - up0.Y; vertices[index].Position.Z = p0.Position.Z - up0.Z; vertices[index].Color = color0; vertices[index].TextureCoordinate.X = texCoordTopLeft.X; vertices[index].TextureCoordinate.Y = texCoordBottomRight.Y; index++; // Top left vertex vertices[index].Position.X = p0.Position.X + up0.X; vertices[index].Position.Y = p0.Position.Y + up0.Y; vertices[index].Position.Z = p0.Position.Z + up0.Z; vertices[index].Color = color0; vertices[index].TextureCoordinate.X = texCoordTopLeft.X; vertices[index].TextureCoordinate.Y = texCoordTopLeft.Y; index++; // Top right vertex vertices[index].Position.X = p1.Position.X + up1.X; vertices[index].Position.Y = p1.Position.Y + up1.Y; vertices[index].Position.Z = p1.Position.Z + up1.Z; vertices[index].Color = color1; vertices[index].TextureCoordinate.X = texCoordBottomRight.X; vertices[index].TextureCoordinate.Y = texCoordTopLeft.Y; index++; // Bottom right vertex vertices[index].Position.X = p1.Position.X - up1.X; vertices[index].Position.Y = p1.Position.Y - up1.Y; vertices[index].Position.Z = p1.Position.Z - up1.Z; vertices[index].Color = color1; vertices[index].TextureCoordinate.X = texCoordBottomRight.X; vertices[index].TextureCoordinate.Y = texCoordBottomRight.Y; #endregion }
/// <summary> /// Loads source sprites referenced in declaration input and packs sprites into a sprite sheet. /// </summary> /// <param name="declaration">Sprite sheet delcaration input.</param> /// <param name="context">Context of the process routine.</param> /// <returns>Sprite sheet content.</returns> public override SpriteSheetContent Process(SpriteSheetDeclaration declaration, ContentProcessorContext context) { if (declaration == null) { throw new ArgumentNullException(nameof(declaration)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } // Collect all texture file paths. // var texturePaths = new HashSet <string>(); foreach (string pathPattern in declaration.PathPatterns) { foreach (string filePath in Glob.Files(Directory.GetCurrentDirectory(), pathPattern)) { texturePaths.Add(filePath); } } // Limit the packed texture based on the target graphics profile. // int maximumDimension = context.TargetProfile == GraphicsProfile.HiDef ? 4096 : 2048; PackedTexture packedTexture = SpritePacker.Pack( configuration: new PackConfiguration(maximumDimension, maximumDimension, this.IsPowerOfTwo, this.IsSquare, this.Padding), spritePaths: texturePaths.ToArray()); // Ensure our output directory exists. // if (!Directory.Exists(context.OutputDirectory)) { Directory.CreateDirectory(context.OutputDirectory); } // Write the packed texture to the output location. // string outputPath = Path.Combine(context.OutputDirectory, $"{declaration.Name}.png"); using (var stream = new FileStream(outputPath, FileMode.Create)) { packedTexture.Texture.Save(stream, ImageFormat.Png); } context.AddOutputFile(outputPath); // Finalize the content to serialize from this processor. // return(new SpriteSheetContent { Name = declaration.Name, SpriteNamesToIndexMapping = packedTexture.SpriteNamesToIndexMapping, SpriteRectangles = packedTexture.SpriteRectangles, Texture = this.BuildTexture($"{declaration.Name}Texture", outputPath, context), }); }
public void PackSkinGraphics(string skinName) { Cleanup(); if (LoadPackedSkin(skinName)) { return; } // Create the list of textures to pack. _packedTextures = new List<PackedTexture>(); _texturesNotPacked = new List<string>(); List<string> files = new List<string>(); string[] skinFiles = Directory.GetFiles(String.Format(@"{0}\media", skinName), "*.png"); files.AddRange(skinFiles); try { string[] themeFiles = Directory.GetFiles(String.Format(@"{0}\themes", skinName), "*.png", SearchOption.AllDirectories); files.AddRange(themeFiles); } catch (DirectoryNotFoundException) { // The themes directory is not required to exist. } string[] tvLogos = Directory.GetFiles(Config.GetSubFolder(Config.Dir.Thumbs, @"tv\logos"), "*.png", SearchOption.AllDirectories); files.AddRange(tvLogos); string[] radioLogos = Directory.GetFiles(Config.GetSubFolder(Config.Dir.Thumbs, "Radio"), "*.png", SearchOption.AllDirectories); files.AddRange(radioLogos); string[] weatherFiles = Directory.GetFiles(String.Format(@"{0}\media\weather", skinName), "*.png"); files.AddRange(weatherFiles); string[] tetrisFiles = Directory.GetFiles(String.Format(@"{0}\media\tetris", skinName), "*.png"); files.AddRange(tetrisFiles); // Determine maximum texture dimensions try { Caps d3dcaps = GUIGraphicsContext.DX9Device.DeviceCaps; _maxTextureWidth = d3dcaps.MaxTextureWidth; _maxTextureHeight = d3dcaps.MaxTextureHeight; Log.Info("TexturePacker: D3D device does support {0}x{1} textures", _maxTextureWidth, _maxTextureHeight); } catch (Exception) { _maxTextureWidth = 2048; _maxTextureHeight = 2048; } if (_maxTextureWidth > MAXTEXTUREDIMENSION) { _maxTextureWidth = MAXTEXTUREDIMENSION; } if (_maxTextureHeight > MAXTEXTUREDIMENSION) { _maxTextureHeight = MAXTEXTUREDIMENSION; } Log.Info("TexturePacker: using {0}x{1} as packed textures limit", _maxTextureWidth, _maxTextureHeight); Log.Info("TexturePacker: using {0}x{1} as single texture limit", _maxTextureWidth / 2, _maxTextureHeight / 2); while (true) { bool ImagesLeft = false; PackedTexture bigOne = new PackedTexture(); bigOne.root = new PackedTextureNode(); bigOne.texture = null; bigOne.textureNo = -1; using (Bitmap rootImage = new Bitmap(_maxTextureWidth, _maxTextureHeight)) { bigOne.root.Rect = new Rectangle(0, 0, _maxTextureWidth, _maxTextureHeight); for (int i = 0; i < files.Count; ++i) { if (files[i] == null) { continue; } files[i] = files[i].ToLowerInvariant(); if (files[i] != string.Empty) { // Ignore files not needed for MP if (files[i].IndexOf("preview.") >= 0) { files[i] = string.Empty; continue; } bool dontAdd; if (AddBitmap(bigOne.root, rootImage, files[i], out dontAdd)) { files[i] = string.Empty; } else { if (dontAdd) { // Keep track of textures that cannot be packed. _texturesNotPacked.Add(files[i]); files[i] = string.Empty; } else { ImagesLeft = true; } } } } if (!Directory.Exists(GUIGraphicsContext.SkinCacheFolder)) { Directory.CreateDirectory(GUIGraphicsContext.SkinCacheFolder); } string fileName = String.Format(@"{0}\packedgfx2{1}.png", GUIGraphicsContext.SkinCacheFolder, _packedTextures.Count); rootImage.Save(fileName, ImageFormat.Png); Log.Debug("TexturePacker: Cache root {0} filled", fileName); } _packedTextures.Add(bigOne); if (!ImagesLeft) { break; } } SavePackedSkin(skinName); }
public bool Get(string fileName, out float uoffs, out float voffs, out float umax, out float vmax, out int iWidth, out int iHeight, out Texture tex, out int textureNo) { uoffs = voffs = umax = vmax = 0.0f; iWidth = iHeight = 0; textureNo = -1; tex = null; if (_packedTextures == null) { return(false); } if (fileName.StartsWith(@"\")) { fileName = fileName.Remove(0, 1); } fileName = fileName.ToLowerInvariant(); if (fileName == string.Empty) { return(false); } int index = 0; PackedTexture bigOne = null; PackedTextureNode foundNode = null; // Look for textures first in the current theme location. Theme textures override default textures. // If the default theme is selected then avoid looking through the theme. if (!GUIThemeManager.CurrentThemeIsDefault) { string skinThemeTexturePath = GUIThemeManager.CurrentTheme + @"\media\"; skinThemeTexturePath = skinThemeTexturePath.ToLowerInvariant(); // If a theme texture exists but was not able to be packed then avoid trying to unpack the texture all together. This prevents // a base skin texture from being unpacked and returned when the base texture could be packed but the overriding theme texture // could not be packed. if (!IsTexturePacked(skinThemeTexturePath + fileName)) { return(false); } foreach (PackedTexture texture in _packedTextures) { if ((foundNode = texture.root.Get(skinThemeTexturePath + fileName)) != null) { bigOne = texture; break; } index++; } } // No theme texture was found. Check the default skin location. if (foundNode == null) { index = 0; foreach (PackedTexture texture in _packedTextures) { if ((foundNode = texture.root.Get(fileName)) != null) { bigOne = texture; break; } index++; } } if (foundNode != null) { uoffs = (float)(foundNode.Rect.Left + 1) / bigOne.root.Rect.Width; voffs = (float)(foundNode.Rect.Top + 1) / bigOne.root.Rect.Height; umax = (float)(foundNode.Rect.Width - 2) / bigOne.root.Rect.Width; vmax = (float)(foundNode.Rect.Height - 2) / bigOne.root.Rect.Height; iWidth = foundNode.Rect.Width - 2; iHeight = foundNode.Rect.Height - 2; if (bigOne.texture == null) { LoadPackedGraphics(index); } tex = bigOne.texture; if (bigOne.textureNo == -1) { unsafe { IntPtr ptr = DirectShowUtil.GetUnmanagedTexture(bigOne.texture); bigOne.textureNo = DXNative.FontEngineAddTexture(ptr.ToInt32(), true, ptr.ToPointer()); Log.Info("TexturePacker: fontengine add texure:{0}", bigOne.textureNo); } } textureNo = bigOne.textureNo; return(true); } return(false); }
/// <summary> /// Adds the specified billboard (4 vertices) to the vertex buffer. /// </summary> /// <param name="b">The billboard.</param> /// <param name="vertices">The vertex buffer.</param> /// <param name="texture">The packed texture.</param> /// <param name="index">The index of the next free slot in the vertex buffer.</param> protected abstract void OnDrawBillboard(ref BillboardArgs b, PackedTexture texture, T[] vertices, int index);
public void PackSkinGraphics(string skinName) { Cleanup(); if (LoadPackedSkin()) { return; } // Create the list of textures to pack. _packedTextures = new List <PackedTexture>(); _texturesNotPacked = new List <string>(); var files = new List <string>(); string[] skinFiles = Directory.GetFiles(String.Format(@"{0}\media", skinName), "*.png"); files.AddRange(skinFiles); try { string[] themeFiles = Directory.GetFiles(String.Format(@"{0}\themes", skinName), "*.png", SearchOption.AllDirectories); files.AddRange(themeFiles); } catch (DirectoryNotFoundException) { // The themes directory is not required to exist. } string[] tvLogos = Directory.GetFiles(Config.GetSubFolder(Config.Dir.Thumbs, @"tv\logos"), "*.png", SearchOption.AllDirectories); files.AddRange(tvLogos); string[] radioLogos = Directory.GetFiles(Config.GetSubFolder(Config.Dir.Thumbs, "Radio"), "*.png", SearchOption.AllDirectories); files.AddRange(radioLogos); string[] weatherFiles = Directory.GetFiles(String.Format(@"{0}\media\weather", skinName), "*.png"); files.AddRange(weatherFiles); string[] tetrisFiles = Directory.GetFiles(String.Format(@"{0}\media\tetris", skinName), "*.png"); files.AddRange(tetrisFiles); // Determine maximum texture dimensions try { Caps capabilities = GUIGraphicsContext.DX9Device.DeviceCaps; _maxTextureWidth = capabilities.MaxTextureWidth; _maxTextureHeight = capabilities.MaxTextureHeight; Log.Info("TexturePacker: D3D device does support {0}x{1} textures", _maxTextureWidth, _maxTextureHeight); } catch (Exception) { _maxTextureWidth = MAXTEXTUREDIMENSION; _maxTextureHeight = MAXTEXTUREDIMENSION; } if (_maxTextureWidth > MAXTEXTUREDIMENSION) { _maxTextureWidth = MAXTEXTUREDIMENSION; } if (_maxTextureHeight > MAXTEXTUREDIMENSION) { _maxTextureHeight = MAXTEXTUREDIMENSION; } Log.Info("TexturePacker: using {0}x{1} as packed textures limit", _maxTextureWidth, _maxTextureHeight); Log.Info("TexturePacker: using {0}x{1} as single texture limit", _maxTextureWidth / 2, _maxTextureHeight / 2); while (true) { bool imagesLeft = false; var bigOne = new PackedTexture { root = new PackedTextureNode(), texture = null, textureNo = -1 }; using (var rootImage = new Bitmap(_maxTextureWidth, _maxTextureHeight)) { bigOne.root.Rect = new Rectangle(0, 0, _maxTextureWidth, _maxTextureHeight); for (int i = 0; i < files.Count; ++i) { if (files[i] == null) { continue; } files[i] = files[i].ToLowerInvariant(); if (files[i] != string.Empty) { // Ignore files not needed for MP if (files[i].IndexOf("preview.", StringComparison.Ordinal) >= 0) { files[i] = string.Empty; continue; } bool dontAdd; if (AddBitmap(bigOne.root, rootImage, files[i], out dontAdd)) { files[i] = string.Empty; } else { if (dontAdd) { // Keep track of textures that cannot be packed. _texturesNotPacked.Add(files[i]); files[i] = string.Empty; } else { imagesLeft = true; } } } } if (!Directory.Exists(GUIGraphicsContext.SkinCacheFolder)) { Directory.CreateDirectory(GUIGraphicsContext.SkinCacheFolder); } string fileName = String.Format(@"{0}\packedgfx2{1}.png", GUIGraphicsContext.SkinCacheFolder, _packedTextures.Count); rootImage.Save(fileName, ImageFormat.Png); Log.Debug("TexturePacker: Cache root {0} filled", fileName); } _packedTextures.Add(bigOne); if (!imagesLeft) { break; } } SavePackedSkin(); }
protected override void OnDrawBillboard(ref BillboardArgs b, PackedTexture texture, VertexPositionColorTexture[] vertices, int index) { #region ----- Billboarding ----- // The billboard orientation is defined by three vectors: normal (pointing to the camera), // up and right (both lying in the billboard plane). // normal and up are given. right is computed using the cross product up x normal. // normal and up should be perpendicular, but usually they are not. Therefore, one vector // must be corrected. For spherical billboards, the normal is fixed and the up vector // is corrected. For cylindrical billboards (= axial billboards), the up vector is fixed // and the b.Normal is corrected. // Normal if (b.Orientation.Normal == BillboardNormal.ViewpointOriented) { Vector3F normal = _cameraPose.Position - b.Position; if (normal.TryNormalize()) { b.Normal = normal; } } // Axis = up vector if (b.Orientation.IsAxisInViewSpace) { b.Axis = _cameraPose.ToWorldDirection(b.Axis); } if (1 - Vector3F.Dot(b.Normal, b.Axis) < Numeric.EpsilonF) { // Normal and axis are parallel. // --> Bend normal by adding a fraction of the camera down vector. b.Normal += _cameraDown * 0.001f; b.Normal.Normalize(); } // Compute right. //Vector3F right = Vector3F.Cross(b.Axis, b.Normal); // Inlined: Vector3F right; right.X = b.Axis.Y * b.Normal.Z - b.Axis.Z * b.Normal.Y; right.Y = b.Axis.Z * b.Normal.X - b.Axis.X * b.Normal.Z; right.Z = b.Axis.X * b.Normal.Y - b.Axis.Y * b.Normal.X; if (!right.TryNormalize()) { right = b.Normal.Orthonormal1; // Normal and axis are parallel --> Choose random perpendicular vector. } if (b.Orientation.IsAxisFixed) { // Make sure normal is perpendicular to right and up. //normal = Vector3F.Cross(right, b.Axis); // Inlined: b.Normal.X = right.Y * b.Axis.Z - right.Z * b.Axis.Y; b.Normal.Y = right.Z * b.Axis.X - right.X * b.Axis.Z; b.Normal.Z = right.X * b.Axis.Y - right.Y * b.Axis.X; // No need to normalize because right and up are normalized and perpendicular. } else { // Make sure axis is perpendicular to normal and right. //b.Axis = Vector3F.Cross(b.Normal, right); // Inlined: b.Axis.X = b.Normal.Y * right.Z - b.Normal.Z * right.Y; b.Axis.Y = b.Normal.Z * right.X - b.Normal.X * right.Z; b.Axis.Z = b.Normal.X * right.Y - b.Normal.Y * right.X; // No need to normalize because normal and right are normalized and perpendicular. } #endregion #region ----- Rotate up and right vectors ----- Vector3F upRotated; Vector3F rightRotated; if (b.Angle != 0.0f) { // Rotate up and right. // Here is the readable code. //Matrix33F rotation = Matrix33F.CreateRotation(b.Normal, b.Angle); //Vector3F upRotated = rotation * b.Axis; //Vector3F rightRotated = rotation * right; // Inlined code: float x = b.Normal.X; float y = b.Normal.Y; float z = b.Normal.Z; float x2 = x * x; float y2 = y * y; float z2 = z * z; float xy = x * y; float xz = x * z; float yz = y * z; float cos = (float)Math.Cos(b.Angle); float sin = (float)Math.Sin(b.Angle); float xsin = x * sin; float ysin = y * sin; float zsin = z * sin; float oneMinusCos = 1.0f - cos; float m00 = x2 + cos * (1.0f - x2); float m01 = xy * oneMinusCos - zsin; float m02 = xz * oneMinusCos + ysin; float m10 = xy * oneMinusCos + zsin; float m11 = y2 + cos * (1.0f - y2); float m12 = yz * oneMinusCos - xsin; float m20 = xz * oneMinusCos - ysin; float m21 = yz * oneMinusCos + xsin; float m22 = z2 + cos * (1.0f - z2); upRotated.X = m00 * b.Axis.X + m01 * b.Axis.Y + m02 * b.Axis.Z; upRotated.Y = m10 * b.Axis.X + m11 * b.Axis.Y + m12 * b.Axis.Z; upRotated.Z = m20 * b.Axis.X + m21 * b.Axis.Y + m22 * b.Axis.Z; rightRotated.X = m00 * right.X + m01 * right.Y + m02 * right.Z; rightRotated.Y = m10 * right.X + m11 * right.Y + m12 * right.Z; rightRotated.Z = m20 * right.X + m21 * right.Y + m22 * right.Z; } else { // Angle is 0 - no rotation. upRotated = b.Axis; rightRotated = right; } #endregion #region ----- Handle texture information and size ----- Vector2F texCoordTopLeft = texture.GetTextureCoordinates(Vector2F.Zero, b.AnimationTime); Vector2F texCoordBottomRight = texture.GetTextureCoordinates(Vector2F.One, b.AnimationTime); // Handle mirroring. if (b.Size.X < 0) { b.Size.X = -b.Size.X; MathHelper.Swap(ref texCoordTopLeft.X, ref texCoordBottomRight.X); } if (b.Size.Y < 0) { b.Size.Y = -b.Size.Y; MathHelper.Swap(ref texCoordTopLeft.Y, ref texCoordBottomRight.Y); } b.Size.X /= 2.0f; b.Size.Y /= 2.0f; // Offset from billboard center to right edge. Vector3F hOffset; hOffset.X = rightRotated.X * b.Size.X; hOffset.Y = rightRotated.Y * b.Size.X; hOffset.Z = rightRotated.Z * b.Size.X; // Offset from reference point to top edge. Vector3F vOffset; vOffset.X = upRotated.X * b.Size.Y; vOffset.Y = upRotated.Y * b.Size.Y; vOffset.Z = upRotated.Z * b.Size.Y; #endregion #region ----- Get Color ----- // Premultiply alpha. Vector4 color4 = new Vector4 { X = b.Color.X * b.Alpha, Y = b.Color.Y * b.Alpha, Z = b.Color.Z * b.Alpha, // Apply blend mode (0 = additive, 1 = alpha blend). W = b.Alpha * b.BlendMode }; var color = new Color(color4); #endregion #region ----- Initializes vertices in vertex array ----- // Bottom left vertex vertices[index].Position.X = b.Position.X - hOffset.X - vOffset.X; vertices[index].Position.Y = b.Position.Y - hOffset.Y - vOffset.Y; vertices[index].Position.Z = b.Position.Z - hOffset.Z - vOffset.Z; vertices[index].Color = color; vertices[index].TextureCoordinate.X = texCoordTopLeft.X; vertices[index].TextureCoordinate.Y = texCoordBottomRight.Y; index++; // Top left vertex vertices[index].Position.X = b.Position.X - hOffset.X + vOffset.X; vertices[index].Position.Y = b.Position.Y - hOffset.Y + vOffset.Y; vertices[index].Position.Z = b.Position.Z - hOffset.Z + vOffset.Z; vertices[index].Color = color; vertices[index].TextureCoordinate.X = texCoordTopLeft.X; vertices[index].TextureCoordinate.Y = texCoordTopLeft.Y; index++; // Top right vertex vertices[index].Position.X = b.Position.X + hOffset.X + vOffset.X; vertices[index].Position.Y = b.Position.Y + hOffset.Y + vOffset.Y; vertices[index].Position.Z = b.Position.Z + hOffset.Z + vOffset.Z; vertices[index].Color = color; vertices[index].TextureCoordinate.X = texCoordBottomRight.X; vertices[index].TextureCoordinate.Y = texCoordTopLeft.Y; index++; // Bottom right vertex vertices[index].Position.X = b.Position.X + hOffset.X - vOffset.X; vertices[index].Position.Y = b.Position.Y + hOffset.Y - vOffset.Y; vertices[index].Position.Z = b.Position.Z + hOffset.Z - vOffset.Z; vertices[index].Color = color; vertices[index].TextureCoordinate.X = texCoordBottomRight.X; vertices[index].TextureCoordinate.Y = texCoordBottomRight.Y; #endregion }
/// <summary> /// Adds a segment of a particle ribbon (4 vertices) to the vertex buffer. /// </summary> /// <param name="p0">The segment start.</param> /// <param name="p1">The segment end.</param> /// <param name="texture">The packed texture.</param> /// <param name="vertices">The vertex buffer.</param> /// <param name="index">The index of the next free slot in the vertex buffer.</param> protected abstract void OnDrawRibbon(ref RibbonArgs p0, ref RibbonArgs p1, PackedTexture texture, T[] vertices, int index);
public override void Render(IList<SceneNode> nodes, RenderContext context, RenderOrder order) { ThrowIfDisposed(); if (nodes == null) throw new ArgumentNullException("nodes"); if (context == null) throw new ArgumentNullException("context"); int numberOfNodes = nodes.Count; if (nodes.Count == 0) return; context.Validate(_effect); var originalRenderTarget = context.RenderTarget; var originalViewport = context.Viewport; var graphicsDevice = context.GraphicsService.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.BlendState = BlendState.Opaque; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.None; int frame = context.Frame; float deltaTime = (float)context.DeltaTime.TotalSeconds; for (int nodeIndex = 0; nodeIndex < numberOfNodes; nodeIndex++) { var cloudNode = nodes[nodeIndex] as CloudLayerNode; if (cloudNode == null) continue; var cloudMap = cloudNode.CloudMap as LayeredCloudMap; if (cloudMap == null) continue; // We update the cloud map only once per frame. if (cloudMap.LastFrame == frame) continue; cloudMap.LastFrame = frame; var layers = cloudMap.Layers; var animationTimes = cloudMap.AnimationTimes; var sources = cloudMap.SourceLayers; var targets = cloudMap.TargetLayers; var renderTargets = cloudMap.LayerTextures; // Animate the cloud map layers. for (int i = 0; i < LayeredCloudMap.NumberOfTextures; i++) { if (layers[i] == null || layers[i].Texture != null) continue; if (cloudMap.Random == null) cloudMap.Random = new Random(cloudMap.Seed); // Make sure there is a user-defined texture or data for procedural textures. if (sources[i] == null) { // Each octave is 128 x 128 (= 1 / 4 of the 512 * 512 noise texture). sources[i] = new PackedTexture(null, _noiseTexture, cloudMap.Random.NextVector2F(0, 1), new Vector2F(0.25f)); targets[i] = new PackedTexture(null, _noiseTexture, cloudMap.Random.NextVector2F(0, 1), new Vector2F(0.25f)); renderTargets[i] = new RenderTarget2D(graphicsDevice, 128, 128, false, SurfaceFormat.Alpha8, DepthFormat.None); } // Update animation time. animationTimes[i] += deltaTime * layers[i].AnimationSpeed; // Update source and target if animation time is beyond 1. if (animationTimes[i] > 1) { // Wrap animation time. animationTimes[i] = animationTimes[i] % 1; // Swap source and target. MathHelper.Swap(ref sources[i], ref targets[i]); // Set target to a new random part of the noise texture. targets[i].Offset = cloudMap.Random.NextVector2F(0, 1); } // Lerp source and target together to get the final noise texture. graphicsDevice.SetRenderTarget(renderTargets[i]); _parameterViewportSize.SetValue(new Vector2(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height)); _parameterTextures[0].SetValue(sources[i].TextureAtlas); _parameterTextures[1].SetValue(targets[i].TextureAtlas); _parameterTexture0Parameters.SetValue(new Vector4(sources[i].Scale.X, sources[i].Scale.Y, sources[i].Offset.X, sources[i].Offset.Y)); _parameterTexture1Parameters.SetValue(new Vector4(targets[i].Scale.X, targets[i].Scale.Y, targets[i].Offset.X, targets[i].Offset.Y)); _parameterLerp.SetValue(animationTimes[i]); _passLerp.Apply(); graphicsDevice.DrawFullScreenQuad(); } // Initialize the cloud map. if (cloudMap.Texture == null || cloudMap.Size != cloudMap.Texture.Width) { cloudMap.Texture.SafeDispose(); var cloudTexture = new RenderTarget2D( graphicsDevice, cloudMap.Size, cloudMap.Size, false, SurfaceFormat.Alpha8, DepthFormat.None); cloudMap.SetTexture(cloudTexture); } // Combine the layers. graphicsDevice.SetRenderTarget((RenderTarget2D)cloudMap.Texture); _parameterViewportSize.SetValue(new Vector2(cloudMap.Texture.Width, cloudMap.Texture.Height)); for (int i = 0; i < LayeredCloudMap.NumberOfTextures; i++) { var layer = layers[i] ?? EmptyLayer; _parameterTextures[i].SetValue(layer.Texture ?? renderTargets[i]); _parameterMatrices[i].SetValue((Matrix)new Matrix44F(layer.TextureMatrix, Vector3F.Zero)); _parameterDensities[i].SetValue(new Vector2(layer.DensityScale, layer.DensityOffset)); } _parameterCoverage.SetValue(cloudMap.Coverage); _parameterDensity.SetValue(cloudMap.Density); _passDensity.Apply(); graphicsDevice.DrawFullScreenQuad(); } savedRenderState.Restore(); graphicsDevice.SetRenderTarget(null); context.RenderTarget = originalRenderTarget; context.Viewport = originalViewport; }
/// <inheritdoc/> protected override void CloneCore(SceneNode source) { // Clone SkyNode properties. base.CloneCore(source); // Clone SkyObjectNode properties. var sourceTyped = (SkyObjectNode)source; AngularDiameter = sourceTyped.AngularDiameter; Texture = sourceTyped.Texture; Alpha = sourceTyped.Alpha; SunDirection = sourceTyped.SunDirection; SunLight = sourceTyped.SunLight; AmbientLight = sourceTyped.AmbientLight; LightWrap = sourceTyped.LightWrap; LightSmoothness = sourceTyped.LightSmoothness; GlowColor0 = sourceTyped.GlowColor0; GlowExponent0 = sourceTyped.GlowExponent0; GlowColor1 = sourceTyped.GlowColor1; GlowExponent1 = sourceTyped.GlowExponent1; GlowCutoffThreshold = sourceTyped.GlowCutoffThreshold; }
public void Update(ParticleSystem particleSystem) { Particles.Clear(); var numberOfParticles = particleSystem.NumberOfActiveParticles; if (numberOfParticles == 0) { // Clear texture reference to allow garbage collection. // (Only relevant, if user switches texture.) Texture = null; return; } // Pose (relative to root particle system) var parent = particleSystem.Parent; if (parent == null) { Pose = Pose.Identity; } else { // Collect all poses except for the root particle system pose. Pose = particleSystem.Pose; while (parent.Parent != null) { Pose = parent.Pose * Pose; parent = parent.Parent; } } // ReferenceFrame ReferenceFrame = particleSystem.ReferenceFrame; // ----- Uniform particle parameters // Texture var packedTextureParameter = TextureParameter as IParticleParameter <PackedTexture>; if (packedTextureParameter != null) { Texture = packedTextureParameter.DefaultValue; } else { var textureParameter = TextureParameter as IParticleParameter <Texture2D>; if (textureParameter != null) { var texture = textureParameter.DefaultValue; if (texture != null) { if (Texture == null || Texture.TextureAtlas != texture) { Texture = new PackedTexture(texture); } } else { Texture = null; } } } // Particles are not rendered without a texture. if (Texture == null) { return; } float aspectRatio = 1.0f; if (Texture != null) { var texture = Texture.TextureAtlas; float textureAspectRatio = (float)texture.Width / texture.Height; Vector2F texCoordTopLeft = Texture.Offset; Vector2F texCoordBottomRight = Texture.Offset + (Texture.Scale / new Vector2F(Texture.NumberOfColumns, Texture.NumberOfRows)); aspectRatio = textureAspectRatio * (texCoordBottomRight.X - texCoordTopLeft.X) / (texCoordBottomRight.Y - texCoordTopLeft.Y); } // AlphaTest AlphaTest = (AlphaTestParameter != null) ? AlphaTestParameter.DefaultValue : 0.0f; // BillboardOrientation BillboardOrientation = (BillboardOrientationParameter != null) ? BillboardOrientationParameter.DefaultValue : BillboardOrientation.ViewPlaneAligned; // DrawOrder DrawOrder = (DrawOrderParameter != null) ? DrawOrderParameter.DefaultValue : 0; // IsDepthSorted IsDepthSorted = (IsDepthSortedParameter != null) ? IsDepthSortedParameter.DefaultValue : false; // Softness Softness = (SoftnessParameter != null) ? SoftnessParameter.DefaultValue : 0; if (Numeric.IsNaN(Softness)) { Softness = -1; } // ParticleType (particles vs. ribbons) IsRibbon = (TypeParameter != null) ? (TypeParameter.DefaultValue == ParticleType.Ribbon) : false; // StartsAtOrigin //StartsAtOrigin = (StartsAtOriginParameter != null) ? StartsAtOriginParameter.DefaultValue : false; // TextureTiling TextureTiling = (TextureTilingParameter != null) ? TextureTilingParameter.DefaultValue : 0; // ----- Varying particle parameters Particles.AddRange(numberOfParticles); // Values are set below. var targetArray = Particles.Array; // Determine default size of particles. If one dimension is missing, calculate the // missing value using the aspect ratio of the texture. Vector2F size = Vector2F.One; if (SizeParameter != null) { size = new Vector2F(SizeParameter.DefaultValue); } if (SizeXParameter != null) { size.X = SizeXParameter.DefaultValue; } if (SizeYParameter != null) { size.Y = SizeYParameter.DefaultValue; } if (SizeParameter == null && SizeXParameter != null && SizeYParameter == null) { size.Y = size.X / aspectRatio; } if (SizeParameter == null && SizeXParameter == null && SizeYParameter != null) { size.X = size.Y * aspectRatio; } // Initialize particles with default values. var defaultParticle = new Particle { Position = (PositionParameter != null) ? PositionParameter.DefaultValue : new Vector3F(), Normal = (NormalParameter != null) ? NormalParameter.DefaultValue : Vector3F.UnitZ, Axis = (AxisParameter != null) ? AxisParameter.DefaultValue : Vector3F.Up, Size = size, Angle = (AngleParameter != null) ? AngleParameter.DefaultValue : 0.0f, Color = (ColorParameter != null) ? ColorParameter.DefaultValue : Vector3F.One, Alpha = (AlphaParameter != null) ? AlphaParameter.DefaultValue : 1.0f, BlendMode = (BlendModeParameter != null) ? BlendModeParameter.DefaultValue : 1.0f, // AnimationTime is initialized with NormalizedAge below. }; for (int i = 0; i < numberOfParticles; i++) { targetArray[i] = defaultParticle; } int startIndex = particleSystem.ParticleStartIndex; int totalCount = numberOfParticles; int count0 = totalCount; int endIndex0 = startIndex + count0; int endIndex1 = 0; if (endIndex0 > particleSystem.MaxNumberOfParticles) { count0 = particleSystem.MaxNumberOfParticles - startIndex; endIndex0 = particleSystem.MaxNumberOfParticles; endIndex1 = numberOfParticles - count0; } // NormalizedAge if (NormalizedAgeParameter != null && !NormalizedAgeParameter.IsUniform) { var sourceArray = NormalizedAgeParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].IsAlive = (sourceArray[sourceIndex] < 1.0f); targetArray[targetIndex].AnimationTime = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].IsAlive = (sourceArray[sourceIndex] < 1.0f); targetArray[targetIndex].AnimationTime = sourceArray[sourceIndex]; } } // Position if (PositionParameter != null && !PositionParameter.IsUniform) { var sourceArray = PositionParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Position = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Position = sourceArray[sourceIndex]; } } // Normal if (NormalParameter != null && !NormalParameter.IsUniform) { var sourceArray = NormalParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Normal = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Normal = sourceArray[sourceIndex]; } } // Axis if (AxisParameter != null && !AxisParameter.IsUniform) { var sourceArray = AxisParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Axis = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Axis = sourceArray[sourceIndex]; } } // Size if (SizeParameter != null && !SizeParameter.IsUniform) { var sourceArray = SizeParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Size = new Vector2F(sourceArray[sourceIndex]); } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Size = new Vector2F(sourceArray[sourceIndex]); } } if (SizeXParameter != null && !SizeXParameter.IsUniform) { var sourceArray = SizeXParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Size.X = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Size.X = sourceArray[sourceIndex]; } } if (SizeYParameter != null && !SizeYParameter.IsUniform) { var sourceArray = SizeYParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Size.Y = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Size.Y = sourceArray[sourceIndex]; } } if (SizeParameter == null && SizeXParameter != null && !SizeXParameter.IsUniform && SizeYParameter == null) { for (int i = 0; i < numberOfParticles; i++) { targetArray[i].Size.Y = targetArray[i].Size.X / aspectRatio; } } if (SizeParameter == null && SizeXParameter == null && SizeYParameter != null && !SizeYParameter.IsUniform) { for (int i = 0; i < numberOfParticles; i++) { targetArray[i].Size.X = targetArray[i].Size.Y * aspectRatio; } } // Angle if (AngleParameter != null && !AngleParameter.IsUniform) { var sourceArray = AngleParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Angle = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Angle = sourceArray[sourceIndex]; } } // Color if (ColorParameter != null && !ColorParameter.IsUniform) { var sourceArray = ColorParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Color = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Color = sourceArray[sourceIndex]; } } // Alpha if (AlphaParameter != null && !AlphaParameter.IsUniform) { var sourceArray = AlphaParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].Alpha = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].Alpha = sourceArray[sourceIndex]; } } // AnimationTime if (AnimationTimeParameter != null) { // AnimationTime has been initialized with NormalizedAge for automatic animations. // But the "AnimationTime" parameter is set explicitly! if (AnimationTimeParameter.IsUniform) { float animationTime = AnimationTimeParameter.DefaultValue; for (int i = 0; i < numberOfParticles; i++) { targetArray[i].AnimationTime = animationTime; } } else { var sourceArray = AnimationTimeParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].AnimationTime = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].AnimationTime = sourceArray[sourceIndex]; } } } // BlendMode if (BlendModeParameter != null && !BlendModeParameter.IsUniform) { var sourceArray = BlendModeParameter.Values; for (int sourceIndex = startIndex, targetIndex = 0; sourceIndex < endIndex0; sourceIndex++, targetIndex++) { targetArray[targetIndex].BlendMode = sourceArray[sourceIndex]; } for (int sourceIndex = 0, targetIndex = count0; sourceIndex < endIndex1; sourceIndex++, targetIndex++) { targetArray[targetIndex].BlendMode = sourceArray[sourceIndex]; } } }
// OnLoad() is called when the GameObject is added to the IGameObjectService. protected override void OnLoad() { var content = _services.GetInstance <ContentManager>(); _skyboxNode = new SkyboxNode(content.Load <TextureCube>("Sky2")) { Color = new Vector3F(SkyExposure), }; // The ambient light. var ambientLight = new AmbientLight { Color = new Vector3F(0.9f, 0.9f, 1f), HdrScale = 0.1f, Intensity = 0.5f, HemisphericAttenuation = 0.8f, }; _ambientLightNode = new LightNode(ambientLight) { Name = "Ambient", }; // The main directional light. var sunlight = new DirectionalLight { Color = new Vector3F(1, 0.9607844f, 0.9078432f), HdrScale = 0.4f, DiffuseIntensity = 1, SpecularIntensity = 1, }; _sunlightNode = new LightNode(sunlight) { Name = "Sunlight", Priority = 10, // This is the most important light. PoseWorld = new Pose(QuaternionF.CreateRotationY(-1.4f) * QuaternionF.CreateRotationX(-0.6f)), // This light uses Cascaded Shadow Mapping. Shadow = new CascadedShadow { #if XBOX PreferredSize = 512, #else PreferredSize = 1024, #endif Prefer16Bit = true, } }; // Add a lens flare for the key light. var lensFlare = new LensFlare(true) { QuerySize = 0.2f, Size = 0.2f, Name = "Sun Flare" }; var lensFlareTexture = content.Load <Texture2D>("LensFlare/LensFlares"); var circleTexture = new PackedTexture("Circle", lensFlareTexture, new Vector2F(0, 0), new Vector2F(0.25f, 0.5f)); var glowTexture = new PackedTexture("Glow", lensFlareTexture, new Vector2F(0.25f, 0), new Vector2F(0.25f, 0.5f)); var ringTexture = new PackedTexture("Ring", lensFlareTexture, new Vector2F(0.5f, 0), new Vector2F(0.25f, 0.5f)); var haloTexture = new PackedTexture("Halo", lensFlareTexture, new Vector2F(0.75f, 0), new Vector2F(0.25f, 0.5f)); var sunTexture = new PackedTexture("Sun", lensFlareTexture, new Vector2F(0, 0.5f), new Vector2F(0.25f, 0.5f)); var streaksTexture = new PackedTexture("Streaks", lensFlareTexture, new Vector2F(0.25f, 0.5f), new Vector2F(0.25f, 0.5f)); var flareTexture = new PackedTexture("Flare", lensFlareTexture, new Vector2F(0.5f, 0.5f), new Vector2F(0.25f, 0.5f)); lensFlare.Elements.Add(new LensFlareElement(-0.2f, 0.55f, 0.0f, new Color(175, 175, 255, 20), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 0.9f, 0.0f, new Color(255, 255, 255, 255), new Vector2F(0.5f, 0.5f), sunTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 1.8f, 0.0f, new Color(255, 255, 255, 128), new Vector2F(0.5f, 0.5f), streaksTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 2.6f, 0.0f, new Color(255, 255, 200, 64), new Vector2F(0.5f, 0.5f), glowTexture)); lensFlare.Elements.Add(new LensFlareElement(0.5f, 0.12f, 0.0f, new Color(60, 60, 180, 35), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.55f, 0.46f, 0.0f, new Color(100, 100, 200, 60), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.6f, 0.17f, 0.0f, new Color(120, 120, 220, 40), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.85f, 0.2f, 0.0f, new Color(60, 60, 255, 100), new Vector2F(0.5f, 0.5f), ringTexture)); lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.2f, 0.0f, new Color(255, 60, 60, 130), new Vector2F(0.5f, 0.5f), flareTexture)); lensFlare.Elements.Add(new LensFlareElement(0.15f, 0.15f, 0.0f, new Color(255, 60, 60, 90), new Vector2F(0.5f, 0.5f), flareTexture)); lensFlare.Elements.Add(new LensFlareElement(1.3f, 0.6f, 0.0f, new Color(60, 60, 255, 180), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.4f, 0.2f, 0.0f, new Color(220, 80, 80, 98), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.1f, 0.0f, new Color(220, 80, 80, 85), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(1.6f, 0.5f, 0.0f, new Color(60, 60, 255, 80), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.8f, 0.3f, 0.0f, new Color(90, 60, 255, 110), new Vector2F(0.5f, 0.5f), ringTexture)); lensFlare.Elements.Add(new LensFlareElement(1.95f, 0.5f, 0.0f, new Color(60, 60, 255, 120), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(2.0f, 0.15f, 0.0f, new Color(60, 60, 255, 85), new Vector2F(0.5f, 0.5f), circleTexture)); // Add lens flare as a child of the sunlight. var lensFlareNode = new LensFlareNode(lensFlare); _sunlightNode.Children = new SceneNodeCollection(); _sunlightNode.Children.Add(lensFlareNode); // Add scene nodes to scene graph. var scene = _services.GetInstance <IScene>(); scene.Children.Add(_skyboxNode); scene.Children.Add(_ambientLightNode); scene.Children.Add(_sunlightNode); }
public void PackSkinGraphics(string skinName) { Cleanup(); if (LoadPackedSkin(skinName)) { return; } _packedTextures = new List<PackedTexture>(); List<string> files = new List<string>(); using (Settings xmlreader = new MPSettings()) { if (xmlreader.GetValueAsBool("debug", "packSkinGfx", true)) { string[] skinFiles = Directory.GetFiles(String.Format(@"{0}\media", skinName), "*.png"); files.AddRange(skinFiles); } // workaround for uncommon rendering implementation of volume osd - it won't show up without packedtextures else { string[] skinFiles = Directory.GetFiles(String.Format(@"{0}\media", skinName), "volume*.png"); string[] forcedCacheFiles = Directory.GetFiles(String.Format(@"{0}\media", skinName), "cached*.png"); files.Add(String.Format(@"{0}\media\Thumb_Mask.png", skinName)); files.AddRange(skinFiles); files.AddRange(forcedCacheFiles); } if (xmlreader.GetValueAsBool("debug", "packLogoGfx", true)) { string[] tvLogos = Directory.GetFiles(Config.GetSubFolder(Config.Dir.Thumbs, @"tv\logos"), "*.png", SearchOption.AllDirectories); string[] radioLogos = Directory.GetFiles(Config.GetSubFolder(Config.Dir.Thumbs, "Radio"), "*.png", SearchOption.AllDirectories); files.AddRange(tvLogos); files.AddRange(radioLogos); } if (xmlreader.GetValueAsBool("debug", "packPluginGfx", true)) { string[] weatherFiles = Directory.GetFiles(String.Format(@"{0}\media\weather", skinName), "*.png"); string[] tetrisFiles = Directory.GetFiles(String.Format(@"{0}\media\tetris", skinName), "*.png"); files.AddRange(weatherFiles); files.AddRange(tetrisFiles); } } // Determine maximum texture dimensions try { Caps d3dcaps = GUIGraphicsContext.DX9Device.DeviceCaps; _maxTextureWidth = d3dcaps.MaxTextureWidth; _maxTextureHeight = d3dcaps.MaxTextureHeight; Log.Info("TexturePacker: D3D device does support {0}x{1} textures", _maxTextureWidth, _maxTextureHeight); } catch (Exception) { _maxTextureWidth = 2048; _maxTextureHeight = 2048; } if (_maxTextureWidth > MAXTEXTUREDIMENSION) { _maxTextureWidth = MAXTEXTUREDIMENSION; } if (_maxTextureHeight > MAXTEXTUREDIMENSION) { _maxTextureHeight = MAXTEXTUREDIMENSION; } Log.Info("TexturePacker: using {0}x{1} as packed textures limit", _maxTextureWidth, _maxTextureHeight); Log.Info("TexturePacker: using {0}x{1} as single texture limit", _maxTextureWidth / 2, _maxTextureHeight / 2); while (true) { bool ImagesLeft = false; PackedTexture bigOne = new PackedTexture(); bigOne.root = new PackedTextureNode(); bigOne.texture = null; bigOne.textureNo = -1; using (Bitmap rootImage = new Bitmap(_maxTextureWidth, _maxTextureHeight)) { bigOne.root.Rect = new Rectangle(0, 0, _maxTextureWidth, _maxTextureHeight); for (int i = 0; i < files.Count; ++i) { if (files[i] == null) { continue; } files[i] = files[i].ToLowerInvariant(); if (files[i] != string.Empty) { // Ignore files not needed for MP if (files[i].IndexOf("preview.") >= 0) { files[i] = string.Empty; continue; } bool dontAdd; if (AddBitmap(bigOne.root, rootImage, files[i], out dontAdd)) { files[i] = string.Empty; } else { if (dontAdd) { files[i] = string.Empty; } else { ImagesLeft = true; } } } } if (!Directory.Exists(GUIGraphicsContext.SkinCacheFolder)) { Directory.CreateDirectory(GUIGraphicsContext.SkinCacheFolder); } string fileName = String.Format(@"{0}\packedgfx2{1}.png", GUIGraphicsContext.SkinCacheFolder, _packedTextures.Count); rootImage.Save(fileName, ImageFormat.Png); Log.Debug("TexturePacker: Cache root {0} filled", fileName); } _packedTextures.Add(bigOne); if (!ImagesLeft) { break; } } SavePackedSkin(skinName); }