/// <summary> /// Creates texture atlas from stream. /// </summary> /// <param name="device"></param> public TextureAtlas ( RenderSystem rs, Stream stream, bool useSRgb = false ) { var device = rs.Game.GraphicsDevice; using ( var br = new BinaryReader(stream) ) { br.ExpectFourCC("ATLS", "texture atlas"); int count = br.ReadInt32(); for ( int i=0; i<count; i++ ) { var element = new Element(); element.Index = i; element.Name = br.ReadString(); element.X = br.ReadInt32(); element.Y = br.ReadInt32(); element.Width = br.ReadInt32(); element.Height = br.ReadInt32(); elements.Add( element ); } int ddsFileLength = br.ReadInt32(); var ddsImageBytes = br.ReadBytes( ddsFileLength ); texture = new UserTexture( rs, ddsImageBytes, useSRgb ); } dictionary = elements.ToDictionary( e => e.Name ); }
/// <summary> /// Draw string using specified font texture, position, text and color. /// Font texture should contain character glyphs arranged in grid 16x16. /// Only ASCII is supported. /// </summary> /// <param name="fontTexture"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="text"></param> /// <param name="color"></param> /// <param name="scale"></param> /// <param name="clipRectIndex"></param> public void DrawDebugString(Texture fontTexture, float x, float y, string text, Color color, float scale, int clipRectIndex ) { int len = text.Length; var duv = 1.0f / 16.0f; for (int i=0; i<len; i++) { int ch = text[i]; var u = (ch%16)/16.0f; var v = (ch/16)/16.0f; DrawUV(fontTexture, x, y, 8 * scale, 8 * scale, color, u, v, duv, duv, clipRectIndex); x += 8 * scale; } }
/// <summary> /// Adds a sprite to a batch of sprites for rendering using the specified texture, destination rectangle, and color. /// </summary> /// <param name="texture"></param> /// <param name="dstRect"></param> /// <param name="color"></param> /// <param name="clipRectIndex"></param> public void Draw ( Texture texture, RectangleF dstRect, Color color, int clipRectIndex=0 ) { texture = texture ?? defaultTexture; float w = texture.Width; float h = texture.Height; DrawUV( texture, dstRect.X, dstRect.Y, dstRect.Width, dstRect.Height, color, 0,0,1,1, clipRectIndex ); }
/// <summary> /// /// </summary> public void DrawUV( Texture srv, Vector3 leftTopCorner, Vector3 rightBottomCorner, Color color, float u, float v, float tw, float th, int clipRectIndex=0 ) { PushQuad(srv, new SpriteVertex(leftTopCorner.X, leftTopCorner.Y, leftTopCorner.Z, color, u + 0, v + 0 , clipRectIndex ), new SpriteVertex(rightBottomCorner.X, leftTopCorner.Y, leftTopCorner.Z, color, u + tw, v + 0 , clipRectIndex ), new SpriteVertex(rightBottomCorner.X, leftTopCorner.Y, rightBottomCorner.Z, color, u + tw, v + th, clipRectIndex ), new SpriteVertex(leftTopCorner.X, leftTopCorner.Y, rightBottomCorner.Z, color, u + 0, v + th, clipRectIndex )); }
/// <summary> /// /// </summary> /// <param name="texture"></param> /// <param name="dstRect"></param> /// <param name="srcRect"></param> /// <param name="offsetX"></param> /// <param name="offsetY"></param> /// <param name="color"></param> /// <param name="clipRectIndex"></param> public void Draw ( Texture texture, Rectangle dstRect, Rectangle srcRect, int offsetX, int offsetY, Color color, int clipRectIndex=0 ) { texture = texture ?? defaultTexture; float w = texture.Width; float h = texture.Height; DrawUV( texture, dstRect.X + offsetY, dstRect.Y + offsetY, dstRect.Width, dstRect.Height, color, srcRect.X/w, srcRect.Y/h, srcRect.Width/w, srcRect.Height/h, clipRectIndex ); }
/// <summary> /// Draw rotated square with specified position, width, height and rotation angle. /// </summary> /// <param name="srv"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="size"></param> /// <param name="angle"></param> /// <param name="color"></param> public void DrawSprite( Texture srv, float x, float y, float size, float angle, Color color, int clipRectIndex=0 ) { DrawSprite( srv, x, y, size, size, angle, color, clipRectIndex ); }
/// <summary> /// Draws beam. /// </summary> /// <param name="srv"></param> /// <param name="p0"></param> /// <param name="p1"></param> /// <param name="color"></param> /// <param name="width"></param> public void DrawBeam ( Texture srv, Vector2 p0, Vector2 p1, Color color0, Color color1, float width, float scale=1, float offset=0, int clipRectIndex=0 ) { if (p1 == p0) { return; } var origin = new Vector3( p0, 0 ); var basisX = new Vector3( p1 - p0, 0 ); var basisY = new Vector3( -basisX.Y, basisX.X, 0 ); basisY.Normalize(); basisY *= (width / 2); float u0 = 0 * scale - offset; float u1 = 1 * scale - offset; PushQuad(srv, new SpriteVertex( origin - basisY , color0, new Vector2(u0, 0)), new SpriteVertex( origin - basisY + basisX , color1, new Vector2(u1, 0)), new SpriteVertex( origin + basisY + basisX , color1, new Vector2(u1, 1)), new SpriteVertex( origin + basisY , color0, new Vector2(u0, 1)) ); }
/// <summary> /// Draw rotated rectangle with specified position, width, height and rotation angle. /// </summary> /// <param name="srv"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="angle"></param> /// <param name="color"></param> public void DrawSprite(Texture srv, float x, float y, float width, float height, float angle, Color color, int clipRectIndex=0 ) { float c = (float)Math.Cos( angle ); float s = (float)Math.Sin( angle ); float nszx = -width / 2; float nszy = -height / 2; float pszx = width / 2; float pszy = height / 2; var p0 = new Vector3( pszx * c + pszy * s + x, - pszx * s + pszy * c + y, 0 ); var p1 = new Vector3( pszx * c + nszy * s + x, - pszx * s + nszy * c + y, 0 ); var p2 = new Vector3( nszx * c + nszy * s + x, - nszx * s + nszy * c + y, 0 ); var p3 = new Vector3( nszx * c + pszy * s + x, - nszx * s + pszy * c + y, 0 ); PushQuad(srv, new SpriteVertex(p0, color, new Vector2(1, 1), clipRectIndex), new SpriteVertex(p1, color, new Vector2(1, 0), clipRectIndex), new SpriteVertex(p2, color, new Vector2(0, 0), clipRectIndex), new SpriteVertex(p3, color, new Vector2(0, 1), clipRectIndex)); }
/// <summary> /// Draw axis-aligned quad with stretched texture. /// </summary> /// <param name="srv"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="w"></param> /// <param name="h"></param> /// <param name="color"></param> /// <param name="clipRectIndex"></param> public void Draw ( Texture srv, float x, float y, float w, float h, Color color, int clipRectIndex=0 ) { var c = color; PushQuad( srv, new SpriteVertex( x + 0, y + 0, 0, c, 0, 0, clipRectIndex ), new SpriteVertex( x + w, y + 0, 0, c, 1, 0, clipRectIndex ), new SpriteVertex( x + w, y + h, 0, c, 1, 1, clipRectIndex ), new SpriteVertex( x + 0, y + h, 0, c, 0, 1, clipRectIndex ) ); }
/// <summary> /// Draw axis-aligned quad with specified UV coordinates. /// </summary> /// <param name="srv"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="w"></param> /// <param name="h"></param> /// <param name="color"></param> /// <param name="u"></param> /// <param name="v"></param> /// <param name="tw"></param> /// <param name="th"></param> public void DrawUV ( Texture srv, float x, float y, float w, float h, Color color, float u, float v, float tw, float th, int clipRectIndex=0 ) { var c = color; PushQuad( srv, new SpriteVertex( x + 0, y + 0, 0, c, u + 0 , v + 0 , clipRectIndex ), new SpriteVertex( x + w, y + 0, 0, c, u + tw, v + 0 , clipRectIndex ), new SpriteVertex( x + w, y + h, 0, c, u + tw, v + th, clipRectIndex ), new SpriteVertex( x + 0, y + h, 0, c, u + 0 , v + th, clipRectIndex ) ); }
/// <summary> /// Draws arbitrary quad with specified vertices. /// </summary> /// <param name="texture"></param> /// <param name="v0"></param> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="v3"></param> internal void DrawQuad ( Texture texture, SpriteVertex v0, SpriteVertex v1, SpriteVertex v2, SpriteVertex v3 ) { PushQuad( texture, v0, v1, v2, v3 ); }
/// <summary> /// /// </summary> /// <param name="texture"></param> /// <param name="v0"></param> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="v3"></param> void PushQuad ( Texture texture, SpriteVertex v0, SpriteVertex v1, SpriteVertex v2, SpriteVertex v3 ) { texture = texture ?? defaultTexture; if ( groups.Count == 0 || groups[groups.Count-1].Texture != texture ) { groups.Add( new Group { Texture = texture, StartSprite = spriteCount } ); } groups[groups.Count-1].SpriteCount++; spriteCount++; vertices.Add( v0 ); vertices.Add( v1 ); vertices.Add( v2 ); vertices.Add( v0 ); vertices.Add( v2 ); vertices.Add( v3 ); dirty = true; }