void TryLoadSDFFont() { // Attempt to load an SDF alternative font // Source SDF font atlas must be an equal POW2 width by height with glyphs arranged in 16x16 grid starting from ASCII 33 // The image must be pre-processed into an alpha-only SDF format prior to import string sdfFontFilename = string.Format("{0}-SDF.png", font.ToString()); string sdfFontPath = Path.Combine(DaggerfallUI.Instance.FontsFolder, sdfFontFilename); if (File.Exists(sdfFontPath)) { // Load source image Texture2D texture = new Texture2D(4, 4, TextureFormat.ARGB32, false); if (!texture.LoadImage(File.ReadAllBytes(sdfFontPath), false)) { Debug.LogErrorFormat("DaggerfallFont: Found a possible SDF font variant but was unable to load from path {0}", sdfFontPath); return; } // Source texture width must equal height if (texture.width != texture.height) { Debug.LogErrorFormat("DaggerfallFont: SDF variant width does not equal height {0}", sdfFontPath); return; } // Source texture must be POW2 if (!PowerOfTwo.IsPowerOfTwo(texture.width)) { Debug.LogErrorFormat("DaggerfallFont: SDF variant is not POW2 {0}", sdfFontPath); return; } // Discover rects int glyphDim = texture.width / sdfGlyphsPerRow; Color32[] colors = texture.GetPixels32(); Rect[] rects = GenerateProportionalRects(ref colors, texture.width, texture.height, sdfGlyphsPerRow, sdfGlyphsPerRow, glyphDim, sdfGlyphCount); // Store settings sdfGlyphDimension = glyphDim; sdfAtlasTexture = texture; sdfAtlasRects = rects; } }
/// <summary> /// Loads all vertices for this DFMesh. /// </summary> /// <param name="model">Model object.</param> private void LoadVertices(ref ModelData model) { // Allocate vertex buffer model.Vertices = new VertexPositionNormalTextureBump[model.DFMesh.TotalVertices]; // Track min and max vectors for bounding box Vector3 min = new Vector3(0, 0, 0); Vector3 max = new Vector3(0, 0, 0); // Loop through all submeshes int vertexCount = 0; foreach (DFMesh.DFSubMesh dfSubMesh in model.DFMesh.SubMeshes) { // Get texture dimensions for this submesh string archivePath = Path.Combine(arena2Path, TextureFile.IndexToFileName(dfSubMesh.TextureArchive)); System.Drawing.Size sz = TextureFile.QuickSize(archivePath, dfSubMesh.TextureRecord); // Ensure texture dimensions are POW2 as TextureManager will be emitting POW2 textures int width = (PowerOfTwo.IsPowerOfTwo(sz.Width)) ? sz.Width : PowerOfTwo.NextPowerOfTwo(sz.Width); int height = (PowerOfTwo.IsPowerOfTwo(sz.Height)) ? sz.Height : PowerOfTwo.NextPowerOfTwo(sz.Height); Vector2 scale = new Vector2( (float)sz.Width / (float)width, (float)sz.Height / (float)height); // Loop through all planes in this submesh foreach (DFMesh.DFPlane dfPlane in dfSubMesh.Planes) { // Copy each point in this plane to vertex buffer foreach (DFMesh.DFPoint dfPoint in dfPlane.Points) { // Daggerfall uses a different axis layout than XNA. // The Y and Z axes should be inverted so the model is displayed correctly. // This also requires a change to winding order in LoadIndices(). Vector3 position = new Vector3(dfPoint.X, -dfPoint.Y, -dfPoint.Z) * GlobalScale; Vector3 normal = new Vector3(dfPoint.NX, -dfPoint.NY, -dfPoint.NZ); // Store vertex data model.Vertices[vertexCount].Position = position; model.Vertices[vertexCount].Normal = normal; model.Vertices[vertexCount].TextureCoordinate = new Vector2( (dfPoint.U / sz.Width) * scale.X, (dfPoint.V / sz.Height) * scale.Y); // Inrement count vertexCount++; // Compare min and max vectors if (position.X < min.X) { min.X = position.X; } if (position.Y < min.Y) { min.Y = position.Y; } if (position.Z < min.Z) { min.Z = position.Z; } if (position.X > max.X) { max.X = position.X; } if (position.Y > max.Y) { max.Y = position.Y; } if (position.Z > max.Z) { max.Z = position.Z; } } } } // Create bounding box model.BoundingBox = new BoundingBox(min, max); // Find model centre Vector3 modelCenter; modelCenter.X = min.X + (max.X - min.X) / 2; modelCenter.Y = min.Y + (max.Y - min.Y) / 2; modelCenter.Z = min.Z + (max.Z - min.Z) / 2; // Find model radius float modelRadius; modelRadius = Vector3.Distance(min, max) / 2; // Create bounding sphere model.BoundingSphere = new BoundingSphere(modelCenter, modelRadius); }
public void BeforeEach() { powerOfTwo = new PowerOfTwo(); }