public BitmapSource GetSpecialSource(ImageSourceId id) { if (id.TextureLookupOriginal) { return(ImageSource); } WriteableBitmap output = null; if (specialSources == null) { specialSources = new Dictionary <ImageSourceId, WriteableBitmap>(); } else { specialSources.TryGetValue(id, out output); } if (output == null) { output = CreateSourceFor(id); specialSources.Add(id, output); } return(output); }
internal ImageSprite GetSprite(ImageSourceId id) { List <ImageSprite> spriteList; sprites.TryGetValue(id, out spriteList); if (spriteList == null) { spriteList = new List <ImageSprite>(); sprites.Add(id, spriteList); } int frame = GraphicsDevice.CurrentSpriteFrameNumber; foreach (ImageSprite sprite in spriteList) { if (sprite.usedOnFrame != frame) { return(sprite); } } // No suitable sprite found, add one: ImageSprite createSprite = new ImageSprite(this, id); GraphicsDevice.AddSprite(createSprite); spriteList.Add(createSprite); return(createSprite); }
WriteableBitmap CreateSourceFor(ImageSourceId id) { BitmapSource original = ImageSource; // Note: need to recreate temporaryImage each time, because Silverlight // has some very strange ideas about when to update the image dimensions Image temporaryImage = new Image(); TintEffect temporaryTintEffect = null; if (id.WantsPreTint) { temporaryTintEffect = TintEffect.Create(id.TintEffectMode); temporaryImage.Effect = temporaryTintEffect; temporaryTintEffect.Color = id.ColorForPreTint; } temporaryImage.Width = original.PixelWidth; temporaryImage.Height = original.PixelHeight; temporaryImage.Source = original; int width, height; SWM.TranslateTransform transform; if (id.UseOriginalDimentions) { width = original.PixelWidth; height = original.PixelHeight; transform = null; } else { width = id.SourceWidth; height = id.SourceHeight; transform = new SWM.TranslateTransform(); transform.X = -id.SourceX; transform.Y = -id.SourceY; } WriteableBitmap output = new WriteableBitmap(width, height); output.Render(temporaryImage, transform); output.Invalidate(); if (temporaryTintEffect != null) { temporaryImage.Effect = null; temporaryTintEffect.Release(); } return(output); }
internal void InternalDraw(Texture2D texture, Vector2 position, Rectangle?sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) { byte r, g, b, a; switch (fixedBlendState) { default: case FixedBlendState.AlphaBlend: // One, 1-SrcAlpha r = color.cR; g = color.cG; b = color.cB; a = color.A; // TODO: Emit warning if premultiplied R,G or B is greater than A. // This would normally cause additive blending. Currently not handled by ExEnSilver. break; case FixedBlendState.NonPremultiplied: // SrcAlpha, 1-SrcAlpha r = color.R; g = color.G; b = color.B; a = color.A; break; case FixedBlendState.Additive: // SrcAlpha, One r = color.R; g = color.G; b = color.B; a = color.A; break; case FixedBlendState.Opaque: // One, Zero r = color.R; g = color.G; b = color.B; a = 255; break; } if (a == 0) // Nothing to draw { return; } // Dynamic rectangle only used if there's actually a source rectangle! bool dynamicRectangle = hintDynamicRectangle && sourceRectangle.HasValue; ImageSourceId id = new ImageSourceId(r, g, b, sourceRectangle, tintEffectMode, hintUseCache, hintDynamicColor, dynamicRectangle); ImageSprite sprite = texture.GetSprite(id); if (hintDynamicColor) { sprite.UpdateDynamicColor(r, g, b); } if (dynamicRectangle) { sprite.UpdateDynamicRectangle(sourceRectangle.Value); } Vector2 sourceSize = sourceRectangle.HasValue ? new Vector2(sourceRectangle.Value.Width, sourceRectangle.Value.Height) : new Vector2(texture.Width, texture.Height); Vector2 sourceOrigin = dynamicRectangle ? new Vector2(sourceRectangle.Value.X, sourceRectangle.Value.Y) : Vector2.Zero; sprite.Transform(position, scale, origin, sourceOrigin, sourceSize, rotation, effects, ref currentMatrix); sprite.SetOpacity(a / 255f); GraphicsDevice.DrawSprite(sprite); }