/// <summary> /// The actual init function called by TextureInfo constructors. /// </summary> /// <param name="texture">The source texture.</param> /// <param name="num_tiles">The number of tiles/cells, horitonally and vertically.</param> /// <param name="source_area">The source rectangle, in UV domain, on which we are going to build the tiles (bottom left is 0,0).</param> public void Initialize( Texture2D texture, Vector2i num_tiles, TRS source_area ) { Texture = texture; TileSizeInUV = source_area.S / num_tiles.Vector2(); NumTiles = num_tiles; m_tiles_uvs = new CachedTileData[ num_tiles.Product() ]; for ( int y=0; y < NumTiles.Y; ++y ) { for ( int x=0; x < NumTiles.X; ++x ) { Vector2i tile_index = new Vector2i( x, y ); TRS tile = TRS.Tile( NumTiles, tile_index, source_area ); // lots of calculation duplicated, but this is an init function int index = tile_index.X + tile_index.Y * NumTiles.X; m_tiles_uvs[ index ] = new CachedTileData() { UV_00 = tile.Point00 , UV_10 = tile.Point10 , UV_01 = tile.Point01 , UV_11 = tile.Point11 }; } } }
//use new TRS { T=a_T, R=a_S, S=a_S } instead? // public TRS( Vector2 a_T , // Vector2 a_R , // Vector2 a_S ) // { // T = a_T; // R = a_R; // S = a_S; // } /// <summary> /// Get a subregion from source_area, given a number of tiles and a tile index, /// assuming evenly spaced subdivision. Typically source_area will be Quad0_1 /// (the unit quad, means the whole texture) and we return the uv info for a /// given tile in the tiled texture. /// </summary> public static TRS Tile( Vector2i num_tiles, Vector2i tile_index, TRS source_area ) { Vector2 num_tiles_f = num_tiles.Vector2(); Vector2 tile_index_f = tile_index.Vector2(); Vector2 tile_size = source_area.S / num_tiles_f; Vector2 X = source_area.X; Vector2 Y = source_area.Y; TRS ret = new TRS(); ret.T = source_area.T + tile_index_f * tile_size; ret.R = source_area.R; ret.S = tile_size; return ret; }
/// <summary> /// </summary> /// <param name="font">The font to use to render characters. Note that FontMap disposes of this Font object.</param> /// <param name="charset">A string containing all the characters you will ever need when drawing text with this FontMap.</param> /// <param name="fontmap_width">The internal with used by the texture (height is adjusted automatically).</param> public void Initialize( Font font, string charset, int fontmap_width = 512 ) { CharSet = new Dictionary< char, CharData >(); CharPixelHeight = font.Metrics.Height; Image image = null; Vector2i totalsize = new Vector2i( 0, 0 ); for ( int k=0; k < 2; ++k ) { Vector2i turtle = new Vector2i( 0, 0 ); // turtle is in Sce.PlayStation.Core.Imaging.Font's coordinate system int max_height = 0; for ( int i=0; i < charset.Length; ++i ) { if ( CharSet.ContainsKey( charset[i] ) ) continue; // this character is already in the map Vector2i char_size = new Vector2i( font.GetTextWidth( charset[i].ToString(), 0, 1 ), font.Metrics.Height ); max_height = Common.Max( max_height, char_size.Y ); if ( turtle.X + char_size.X > fontmap_width ) { // hit the right side, go to next line turtle.X = 0; turtle.Y += max_height; // Sce.PlayStation.Core.Imaging.Font's coordinate system: top is 0, so we += to move down max_height = 0; // make sure we are noit going to newline forever due to lack of fontmap_width Common.Assert( char_size.Y <= fontmap_width ); } if ( k > 0 ) { // that starts from top left image.DrawText( charset[i].ToString(), new ImageColor(255,255,255,255), font , new ImagePosition( turtle.X, turtle.Y ) ); var uv = new Bounds2( turtle.Vector2() / totalsize.Vector2() , ( turtle + char_size ).Vector2() / totalsize.Vector2() ); // now fix the UV to be in GameEngine2D's UV coordinate system, where 0,0 is bottom left uv = uv.OutrageousYVCoordFlip().OutrageousYTopBottomSwap(); CharSet.Add( charset[i], new CharData(){ UV = uv, PixelSize = char_size.Vector2()} ); } turtle.X += char_size.X; if ( k == 0 ) { totalsize.X = Common.Max( totalsize.X, turtle.X ); totalsize.Y = Common.Max( totalsize.Y, turtle.Y + max_height ); } } if ( k == 0 ) { // System.Console.WriteLine( "FontMap.Initialize: totalsize " + totalsize ); image = new Image( ImageMode.A, new ImageSize( totalsize.X, totalsize.Y ), new ImageColor(0,0,0,0) ); CharSet.Clear(); // we want to go through the same add logic on second pass, so clear } } Texture = new Texture2D( image.Size.Width, image.Size.Height, false, PixelFormat.Luminance ); Texture.SetPixels( 0, image.ToBuffer() ); // image.Export("uh?","hey.png"); image.Dispose(); { // cache ascii entries so we can skip TryGetValue logic for those m_ascii_char_data = new CharData[ AsciiCharSet.Length ]; m_ascii_char_data_valid = new bool[ AsciiCharSet.Length ]; for ( int i=0; i < AsciiCharSet.Length; ++i ) { CharData cdata; m_ascii_char_data_valid[i] = CharSet.TryGetValue( AsciiCharSet[i], out cdata ); m_ascii_char_data[i] = cdata; } } // dispose of the font by default font.Dispose(); }