public LevelGrid(float size) { this.Size = size; var bitmap = (Bitmap) Image.FromFile(LocalIo.Resources.GetFile("level.bmp").Uri); var (width, height) = (bitmap.Width, bitmap.Height); var boolGrid = new FinSparseGrid<bool>(bitmap.Width, bitmap.Height, false) { ShouldThrowExceptions = false, }; for (var y = 0; y < height; ++y) { for (var x = 0; x < width; ++x) { var color = bitmap.GetPixel(x, y); if (color.R == 0) { boolGrid[x, y] = true; } } } this.tiles_ = new FinSparseGrid<LevelTileTypes>( bitmap.Width, bitmap.Height, LevelTileTypes.EMPTY) { ShouldThrowExceptions = false, }; foreach (var node in boolGrid) { if (!node.Value) { continue; } var (c, r) = (node.C, node.R); var tile = LevelTileTypes.EMPTY; var isFloor = !boolGrid[c, r - 1]; if (isFloor) { tile |= LevelTileTypes.FLOOR; } var isCeiling = !boolGrid[c, r + 1]; if (isCeiling) { tile |= LevelTileTypes.CEILING; } var isLeftWall = !boolGrid[c - 1, r]; if (isLeftWall) { tile |= LevelTileTypes.LEFT_WALL; } var isRightWall = !boolGrid[c + 1, r]; if (isRightWall) { tile |= LevelTileTypes.RIGHT_WALL; } this.tiles_[c, r] = tile; } boolGrid.Clear(); }
public IFont LoadFont(string fontFileName) { using var library = new Library(); var bytes = LocalFileUtil.ReadBytes( LocalIo.Resources.GetFile("fonts/" + fontFileName)); using var face = new Face(library, bytes, 0); const uint fontSize = 32; face.SetPixelSizes(0, fontSize); var supportedCharCodes = Enumerable.Range(32, 128); // Look up total width and max height to calculate atlas size. int atlasPadding = 2; int atlasWidth; int atlasHeight; int extraAtlasHeight; { int totalGlyphWidth = 0; int maxGlyphHeight = 0; foreach (var supportedCharCode in supportedCharCodes) { face.LoadChar((uint)supportedCharCode, LoadFlags.Render | LoadFlags.Monochrome, LoadTarget.Mono); var faceGlyph = face.Glyph; var bitmap = faceGlyph.Bitmap; totalGlyphWidth += bitmap.Width + atlasPadding; maxGlyphHeight = Math.Max(maxGlyphHeight, bitmap.Rows); } atlasWidth = (int)Math.Pow(2, Math.Ceiling( Math.Log(totalGlyphWidth) / Math.Log(2))); atlasHeight = (int)Math.Pow(2, Math.Ceiling( Math.Log(maxGlyphHeight) / Math.Log(2))); extraAtlasHeight = atlasHeight - maxGlyphHeight; } var fontGlyphs = new Dictionary <char, FontGlyph>(); var atlasPixelGrid = new FinSparseGrid <FinColor>(atlasWidth, atlasHeight, ColorConstants.TRANSPARENT_BLACK); var atlasImageData = new ImageData(ImageType.RGBA, atlasPixelGrid); var x = 0; foreach (var supportedCharCode in supportedCharCodes) { face.LoadChar((uint)supportedCharCode, LoadFlags.Default | LoadFlags.Render, LoadTarget.Normal); // LoadChar() has loaded contents into Glyph. var faceGlyph = face.Glyph; // TODO: Is it possible to load this directly into the texture? var bitmap = faceGlyph.Bitmap; var width = bitmap.Width; var height = bitmap.Rows; byte[]? bufferData = null; try { bufferData = bitmap.BufferData; } catch (Exception e) { // TODO: This should probably not happen. } if (bufferData != null) { for (var r = 0; r < height; ++r) { for (var c = 0; c < width; ++c) { var i = r * width + c; var alpha = bufferData[i]; var color = FinColor.FromRgbaB(255, 255, 255, alpha); atlasPixelGrid[x + c, r] = color; } } } var leftU = (1d * x) / atlasWidth; var rightU = (1d * (x + width)) / atlasWidth; var topV = 0d; var bottomV = (1d * height) / atlasHeight; var uvCoords = ImmutableArray.Create(new (double, double)[] {