/** * Creates a BunnyMark with a certain number of Wabbits. * * @param count * The number of wabbits. * @param rect * You can define a rectangle for the borders of the BunnyMark. If you don't specify the rectangle the complete stage will be used. */ public BunnyMarkSimple(int count = 100, Rectangle rect=null) { Touchable = false; mCount = count; if (rect != null) mRectangle = rect; mTexture = SimpleTextureLoader.LoadAndroidResource(SparrowSharp.Samples.Android.Resource.Drawable.wabbit_alpha); AddedToStage += AddedToStageHandler; }
public TextureInfo(Rectangle region, Rectangle frame, bool rotated) { if (region != null) { Region = region.Copy(); } if (frame != null) { Frame = frame.Copy(); } Rotated = rotated; }
public bool Contains(Rectangle rectangle) { if (rectangle == null) { return false; } float rX = rectangle.X; float rY = rectangle.Y; float rWidth = rectangle.Width; float rHeight = rectangle.Height; return rX >= X && rX + rWidth <= X + Width && rY >= Y && rY + rHeight <= Y + Height; }
/// <summary> /// Initializes a render texture with a certain ARGB color (0xAARRGGBB) and a scale factor. /// </summary> public RenderTexture(float width, float height, uint argbFillColor = 0x0, float scale = 1.0f) { int legalWidth = NumberUtil.NextPowerOfTwo(width * scale); int legalHeight = NumberUtil.NextPowerOfTwo(height * scale); TextureProperties properties = new TextureProperties { TextureFormat = Sparrow.Textures.TextureFormat.Rgba8888, Scale = scale, Width = legalWidth, Height = legalHeight, NumMipmaps = 0, PremultipliedAlpha = true }; Rectangle region = new Rectangle(0, 0, width, height); GLTexture glTexture = new GLTexture(IntPtr.Zero, properties); Init(glTexture, region); _renderSupport = new RenderSupport(); Clear(argbFillColor, ColorUtil.GetA(argbFillColor) / 255.0f); }
public override Rectangle BoundsInSpace(DisplayObject targetSpace) { Point bottomRight; if (targetSpace == this) { // optimization bottomRight = _vertexData.PositionAt(3); return new Rectangle(0.0f, 0.0f, bottomRight.X, bottomRight.Y); } else if (targetSpace == Parent && Rotation == 0.0f) { // optimization float scaleX = ScaleX; float scaleY = ScaleY; bottomRight = _vertexData.PositionAt(3); Rectangle resultRect = new Rectangle(X - PivotX * scaleX, Y - PivotY * scaleY, bottomRight.X * ScaleX, bottomRight.Y * ScaleY); if (scaleX < 0.0f) { resultRect.Width *= -1.0f; resultRect.X -= resultRect.Width; } if (scaleY < 0.0f) { resultRect.Height *= -1.0f; resultRect.Top -= resultRect.Height; } return resultRect; } else { Matrix transformationMatrix = TransformationMatrixToSpace(targetSpace); return _vertexData.BoundsAfterTransformation(transformationMatrix, 0, 4); } }
private void Redraw() { if (_requiresRedraw) { _contents.Reset(); BitmapFont bitmapFont; bitmapFonts.TryGetValue(_fontName, out bitmapFont); if (bitmapFont == null) { throw new InvalidOperationException("bitmap font " + _fontName + " not registered!"); } bitmapFont.FillQuadBatch(_contents, _hitArea.Width, _hitArea.Height, _text, _fontSize, _color, _hAlign, _vAlign, _autoScale, _kerning); _textBounds = null; // will be created on demand _requiresRedraw = false; } }
private void UpdateBuffers(Rectangle bounds) { Vertex[] vertices = _vertexData.Vertices; vertices[0].Position = new Vector2(bounds.X, bounds.Top); vertices[1].Position = new Vector2(bounds.Right, bounds.Top); vertices[2].Position = new Vector2(bounds.X, bounds.Bottom); vertices[3].Position = new Vector2(bounds.Right, bounds.Bottom); const int indexSize = sizeof(ushort) * 6; const int vertexSize = Vertex.SIZE * 4; if (_vertexBufferName == 0) { GL.GenBuffers (1, out _vertexBufferName); GL.BindBuffer (BufferTarget.ArrayBuffer, _vertexBufferName); GL.GenBuffers (1, out _indexBufferName); GL.BindBuffer (BufferTarget.ElementArrayBuffer, _indexBufferName); GL.BufferData (BufferTarget.ElementArrayBuffer, (IntPtr)indexSize, _indexData, BufferUsage.StaticDraw); } GL.BindBuffer (BufferTarget.ArrayBuffer, _vertexBufferName); GL.BufferData (BufferTarget.ArrayBuffer, (IntPtr)vertexSize, _vertexData.Vertices, BufferUsage.StaticDraw); }
private void CalcBounds(DisplayObject obj, Stage stage, float scale, bool intersectWithStage, out Rectangle bounds, out Rectangle boundsPOT) { float marginX; float marginY; // optimize for full-screen effects if (obj == stage || obj == SparrowSharpApp.Root) { marginX = marginY = 0; bounds = new Rectangle(0, 0, stage.Width, stage.Height); } else { marginX = MarginX; marginY = MarginY; bounds = obj.BoundsInSpace(stage); } if (intersectWithStage) bounds = bounds.Intersection(stage.Bounds); boundsPOT = null; Rectangle result = bounds; if (!result.IsEmpty()) { // the bounds are a rectangle around the object, in stage coordinates, // and with an optional margin. bounds.Inflate(marginX, marginY); // To fit into a POT-texture, we extend it towards the right and bottom. int minSize = (int)(MIN_TEXTURE_SIZE / scale); float minWidth = result.Width > minSize ? result.Width : minSize; float minHeight = result.Height > minSize ? result.Height : minSize; boundsPOT = new Rectangle(result.X, result.Top, NumberUtil.NextPowerOfTwo(minWidth * scale) / scale, NumberUtil.NextPowerOfTwo(minHeight * scale) / scale); } }
/// <summary> /// Updates the scissor rectangle using the current clipping rectangle. This method is called /// automatically when either the projection matrix or the clipping rectangle changes. /// </summary> private void ApplyClipRect() { FinishQuadBatch(); Context context = SparrowSharpApp.Context; if (context == null) { return; } if (_clipRectStackSize > 0) { int width; int height; Rectangle rect = _clipRectStack[_clipRectStackSize - 1]; Rectangle clipRect = new Rectangle(); Texture renderTarget = context.RenderTarget; if (renderTarget != null) { width = (int)renderTarget.NativeWidth; height = (int)renderTarget.NativeHeight; } else { width = (int)SparrowSharpApp.Stage.DrawableWidth; height = (int)SparrowSharpApp.Stage.DrawableHeight; } // convert to pixel coordinates (matrix transformation ends up in range [-1, 1]) Point topLeft = _projectionMatrix.TransformPoint(rect.X, rect.Top); if (renderTarget != null) { topLeft.Y = -topLeft.Y; } clipRect.X = (topLeft.X * 0.5f + 0.5f) * width; clipRect.Top = (0.5f - topLeft.Y * 0.5f) * height; Point bottomRight = _projectionMatrix.TransformPoint(rect.Right, rect.Bottom); if (renderTarget != null) { bottomRight.Y = -bottomRight.Y; } clipRect.Right = (bottomRight.X * 0.5f + 0.5f) * width; clipRect.Bottom = (0.5f - bottomRight.Y * 0.5f) * height; // flip y coordiantes when rendering to backbuffer if (renderTarget == null) { clipRect.Top = height - clipRect.Top - clipRect.Height; } Rectangle bufferRect = new Rectangle(0, 0, width, height); Rectangle scissorRect = clipRect.Intersection(bufferRect); // a negative rectangle is not allowed if (scissorRect.Width < 0 || scissorRect.Height < 0) { scissorRect.Empty(); } context.ScissorBox = scissorRect; } else { context.ScissorBox = null; } }
/// <summary> /// Determines whether this instance is equal the specified other with a small Epsilon error margin. /// </summary> public bool IsEqual(Rectangle other) { if (other == this) { return true; } if (other == null) { return false; } return NumberUtil.Equals(X, other.X) && NumberUtil.Equals(Y, other.Y) && NumberUtil.Equals(Width, other.Width) && NumberUtil.Equals(Height, other.Height); }
public void CopyFromRectangle(Rectangle rectangle) { X = rectangle.X; Y = rectangle.Y; Width = rectangle.Width; Height = rectangle.Height; }
/// <summary> /// Returns a rectangle that encompasses both rectangles /// </summary> public Rectangle Union(Rectangle rectangle) { if (rectangle == null) { return null; } float left = Math.Max(X, rectangle.X); float right = Math.Min(X + Width, rectangle.X + rectangle.Width); float top = Math.Max(Y, rectangle.Y); float bottom = Math.Min(Y + Height, rectangle.Y + rectangle.Height); return new Rectangle(left, top, right - left, bottom - top); }
public bool Intersects(Rectangle rectangle) { if (rectangle == null) { return false; } float rX = rectangle.X; float rY = rectangle.Y; float rWidth = rectangle.Width; float rHeight = rectangle.Height; bool outside = (rX <= X && rX + rWidth <= X) || (rX >= X + Width && rX + rWidth >= X + Width) || (rY <= Y && rY + rHeight <= Y) || (rY >= Y + Height && rY + rHeight >= Y + Height); return !outside; }
private void ParseAndLoadChars(XmlDocument xml, float scale) { XmlNodeList charNodes = xml.GetElementsByTagName("char"); for (int i = 0; i < charNodes.Count; i++) { XmlAttributeCollection attributes = charNodes[i].Attributes; float x = Convert.ToSingle(attributes["x"].Value); float y = Convert.ToSingle(attributes["y"].Value); float width = Convert.ToSingle(attributes["width"].Value); float height = Convert.ToSingle(attributes["height"].Value); float frameX = 0; if (_fontTexture.Frame != null) { frameX = _fontTexture.Frame.X; } float frameY = 0; if (_fontTexture.Frame != null) { frameY = _fontTexture.Frame.Y; } Rectangle region = new Rectangle(x / scale + frameX, y / scale + frameY, width / scale, height / scale); SubTexture texture = new SubTexture(_fontTexture, region); int charId = Convert.ToInt32(attributes["id"].Value); float xOffset = Convert.ToSingle(attributes["xoffset"].Value); float yOffset = Convert.ToSingle(attributes["yoffset"].Value); float xAdvance = Convert.ToSingle(attributes["xadvance"].Value); BitmapChar bitmapChar = new BitmapChar(charId, texture, xOffset, yOffset, xAdvance); _chars.Add(charId, bitmapChar); } }
/// <summary> /// Initializes a subtexture with a region (in points) of another texture, using a frame rectangle /// to place the texture within an image. If 'rotated' is 'true', the subtexture will show the base /// region rotated by 90 degrees (CCW). If frame is null, it will use the whole texture. /// </summary> public SubTexture(Texture texture, Rectangle region = null, Rectangle frame = null, bool rotated = false) { Init(texture, region, frame, rotated); }
protected void Init(Texture texture, Rectangle region = null, Rectangle frame = null, bool rotated = false) { if (region == null) region = new Rectangle(0.0f, 0.0f, texture.Width, texture.Height); _parent = texture; if (_frame != null) { _frame = frame.Copy(); } _transformationMatrix = Matrix.Create(); _width = rotated ? region.Height : region.Width; _height = rotated ? region.Width : region.Height; if (rotated) { _transformationMatrix.Translate(0, -1); _transformationMatrix.Rotate((float)Math.PI / 2.0f); } _transformationMatrix.Scale(region.Width / texture.Width, region.Height / texture.Height); _transformationMatrix.Translate(region.X / texture.Width, region.Top / texture.Height); }
/// <summary> /// The clipping rectangle can be used to limit rendering in the current render target to a certain /// area. This method expects the rectangle in stage coordinates. Internally, it uses the /// 'glScissor' command of OpenGL, which works with pixel coordinates. Any pushed rectangle is /// intersected with the previous rectangle; the method returns that intersection. /// </summary> public Rectangle PushClipRect(Rectangle clipRect) { if (_clipRectStack.Count < _clipRectStackSize + 1) { _clipRectStack.Add(new Rectangle()); } Rectangle rectangle = _clipRectStack[_clipRectStackSize]; rectangle.CopyFromRectangle(clipRect); if (_clipRectStackSize > 0) { rectangle = rectangle.Intersection(_clipRectStack[_clipRectStackSize - 1]); } _clipRectStackSize++; ApplyClipRect(); return rectangle; }