Exemplo n.º 1
0
        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;
            }
        }
Exemplo n.º 2
0
        /// <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);
        }