예제 #1
0
        private static StaticMesh LoadObj(string staticMeshId, string filePath)
        {
            // These are temporarily needed lists for storing the parsed data as you read it.
            // Its better to use "ListArrays" vs "Lists" because they will be accessed by indeces
            // by the faces of the obj file.
            List_Array <float> fileVerteces           = new List_Array <float>(10000);
            List_Array <float> fileNormals            = new List_Array <float>(10000);
            List_Array <float> fileTextureCoordinates = new List_Array <float>(10000);
            List_Array <int>   fileIndeces            = new List_Array <int>(10000);

            // Obj files are not required to include texture coordinates or normals
            bool hasTextureCoordinates = true;
            bool hasNormals            = true;

            // Lets read the file and handle each line separately for ".obj" files
            using (StreamReader reader = new StreamReader(filePath))
            {
                int lineNumber = 1;
                while (!reader.EndOfStream)
                {
                    try
                    {
                        string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        switch (parameters[0])
                        {
                        // Vertex
                        case "v":
                            fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                            fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                            fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture));
                            break;

                        // Texture Coordinate
                        case "vt":
                            fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                            fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                            break;

                        // Normal
                        case "vn":
                            fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                            fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                            fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture));
                            break;

                        // Face
                        case "f":
                            //if (parameters.Length < 4)
                            //  throw new StaticModelManagerException("obj file corrupt.");
                            int first = fileIndeces.Count;
                            for (int i = 1; i < parameters.Length; i++)
                            {
                                if (i > 3)
                                {
                                    // Triangulate using the previous two verteces
                                    // NOTE: THIS MAY BE INCORRECT! I COULD NOT YET FIND DOCUMENTATION
                                    // ON THE TRIANGULATION DONE BY BLENDER (WORKS FOR QUADS AT LEAST)

                                    //// Last two (triangle strip)
                                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);

                                    // First then previous (triangle fan)
                                    fileIndeces.Add(fileIndeces[first]);
                                    fileIndeces.Add(fileIndeces[first + 1]);
                                    fileIndeces.Add(fileIndeces[first + 2]);
                                    fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                                    fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                                    fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                                }

                                // Now include the new vertex
                                string[] indexReferences = parameters[i].Split('/');
                                //if (indexReferences[0] == "")
                                //  throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition):" + filePath);
                                fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture));

                                if (hasNormals && indexReferences.Length < 3)
                                {
                                    hasNormals = false;
                                }
                                if (hasTextureCoordinates && (indexReferences.Length < 2 || indexReferences[1] == ""))
                                {
                                    hasTextureCoordinates = false;
                                }

                                if (hasTextureCoordinates && indexReferences[1] != "")
                                {
                                    fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture));
                                }
                                else
                                {
                                    fileIndeces.Add(0);
                                }

                                if (hasNormals && indexReferences[2] != "")
                                {
                                    fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture));
                                }
                                else
                                {
                                    fileIndeces.Add(0);
                                }
                            }
                            break;
                        }
                    }
                    catch
                    {
                        string[] pathSplit = filePath.Split('\\');
                        throw new StaticModelManagerException("Could not load model " + pathSplit[pathSplit.Length - 1] +
                                                              ". There is a corruption on line " + lineNumber + ".");
                    }
                    lineNumber++;
                }
            }

            // Pull the final vertex order out of the indexed references
            // Note, arrays start at 0 but the index references start at 1
            float[] verteces = new float[fileIndeces.Count];
            for (int i = 0; i < fileIndeces.Count; i += 3)
            {
                int index = (fileIndeces[i] - 1) * 3;
                verteces[i]     = fileVerteces[index];
                verteces[i + 1] = fileVerteces[index + 1];
                verteces[i + 2] = fileVerteces[index + 2];
            }

            float[] textureCoordinates = null;
            if (hasTextureCoordinates)
            {
                // Pull the final texture coordinates order out of the indexed references
                // Note, arrays start at 0 but the index references start at 1
                // Note, every other value needs to be inverse (not sure why but it works :P)
                textureCoordinates = new float[fileIndeces.Count / 3 * 2];
                for (int i = 1; i < fileIndeces.Count; i += 3)
                {
                    int index  = (fileIndeces[i] - 1) * 2;
                    int offset = (i - 1) / 3;
                    textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index];
                    textureCoordinates[i - offset]     = 1 - fileTextureCoordinates[(index + 1)];
                }
            }

            float[] normals = null;
            if (hasNormals)
            {
                // Pull the final normal order out of the indexed references
                // Note, arrays start at 0 but the index references start at 1
                normals = new float[fileIndeces.Count];
                for (int i = 2; i < fileIndeces.Count; i += 3)
                {
                    int index = (fileIndeces[i] - 1) * 3;
                    normals[i - 2] = fileNormals[index];
                    normals[i - 1] = fileNormals[(index + 1)];
                    normals[i]     = fileNormals[(index + 2)];
                }
            }

            int vertexBufferId;

            if (verteces != null)
            {
                // Make the vertex buffer on the GPU
                GL.GenBuffers(1, out vertexBufferId);
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId);
                GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw);
                int bufferSize;
                GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                if (verteces.Length * sizeof(float) != bufferSize)
                {
                    throw new StaticModelManagerException("Vertex array not uploaded correctly");
                }
                // Deselect the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            }
            else
            {
                vertexBufferId = 0;
            }

            int textureCoordinateBufferId;

            if (hasTextureCoordinates && textureCoordinates != null)
            {
                // Make the texture coordinate buffer on the GPU
                GL.GenBuffers(1, out textureCoordinateBufferId);
                GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId);
                GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw);
                int bufferSize;
                GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                if (textureCoordinates.Length * sizeof(float) != bufferSize)
                {
                    throw new StaticModelManagerException("TexCoord array not uploaded correctly");
                }
                // Deselect the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            }
            else
            {
                textureCoordinateBufferId = 0;
            }

            int normalBufferId;

            if (hasNormals && normals != null)
            {
                // Make the normal buffer on the GPU
                GL.GenBuffers(1, out normalBufferId);
                GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId);
                GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw);
                int bufferSize;
                GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                if (normals.Length * sizeof(float) != bufferSize)
                {
                    throw new StaticModelManagerException("Normal array not uploaded correctly");
                }
                // Deselect the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            }
            else
            {
                normalBufferId = 0;
            }

            return(new StaticMesh(
                       filePath,
                       staticMeshId,
                       vertexBufferId,
                       0, // Obj files don't support vertex colors
                       textureCoordinateBufferId,
                       normalBufferId,
                       0, // I don't support an index buffer at this time
                       verteces.Length,
                       null));
        }
예제 #2
0
        /// <summary>DONT USE THIS FUNCTION!!! This is an experimental file type I may use in the future.</summary>
        public static StaticModel LoadSevenModelFromDisk(string staticModelId, string filePath)
        {
            // These are temporarily needed lists for storing the parsed data as you read it.
            List_Array <float> fileVerteces           = new List_Array <float>(1000);
            List_Array <float> fileNormals            = new List_Array <float>(1000);
            List_Array <float> fileTextureCoordinates = new List_Array <float>(1000);
            List_Array <int>   fileIndeces            = new List_Array <int>(1000);
            Texture            texture  = null;
            string             meshName = "defaultMeshName";

            AvlTree <StaticMesh> meshes = new AvlTree_Linked <StaticMesh>(StaticMesh.CompareTo);

            // Lets read the file and handle each line separately for ".obj" files
            using (StreamReader reader = new StreamReader(filePath))
            {
                while (!reader.EndOfStream)
                {
                    string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    switch (parameters[0])
                    {
                    // MeshName
                    case "m":
                        meshName = parameters[1];
                        break;

                    // Texture
                    case "t":
                        if (!TextureManager.TextureExists(parameters[1]))
                        {
                            TextureManager.LoadTexture(parameters[1], parameters[2]);
                        }
                        texture = TextureManager.Get(parameters[1]);
                        break;

                    // Vertex
                    case "v":
                        fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                        fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                        fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture));
                        break;

                    // Texture Coordinate
                    case "vt":
                        fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                        fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                        break;

                    // Normal
                    case "vn":
                        fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                        fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                        fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture));
                        break;

                    // Face
                    case "f":
                        // DEVELOPMENT NOTE: The following triangulation algorithm works, but it
                        // could be optimized beyond its current state.

                        // The following variables are used for triangulation of a polygon
                        // with greater than three verteces.
                        int firstPosition, firstTextureCoordinates, firstNormal,
                            secondPosition, secondTextureCoordinates, secondNormal;
                        if (parameters.Length > 3)
                        {
                            // First Vertex (we have to store it this way for possible triangulation)
                            string[] indexReferences = parameters[1].Split('/');
                            if (indexReferences[0] == "")
                            {
                                throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath);
                            }
                            firstPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture);
                            if (indexReferences[1] != "")
                            {
                                firstTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture);
                            }
                            else
                            {
                                firstTextureCoordinates = 0;
                            }
                            if (indexReferences[2] != "")
                            {
                                firstNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture);
                            }
                            else
                            {
                                firstNormal = 0;
                            }

                            // Second Vertex (we have to store it this way for possible triangulation)
                            indexReferences = parameters[2].Split('/');
                            if (indexReferences[0] == "")
                            {
                                throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath);
                            }
                            secondPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture);
                            if (indexReferences[1] != "")
                            {
                                secondTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture);
                            }
                            else
                            {
                                secondTextureCoordinates = 0;
                            }
                            if (indexReferences[2] != "")
                            {
                                secondNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture);
                            }
                            else
                            {
                                secondNormal = 0;
                            }
                        }
                        else
                        {
                            throw new StaticModelManagerException("ERROR: obj file corrupted:" + filePath);
                        }

                        // Verteces past the first two
                        for (int i = 3; i < parameters.Length; i++)
                        {
                            // Triangulate using the first two verteces
                            fileIndeces.Add(firstPosition);
                            fileIndeces.Add(firstTextureCoordinates);
                            fileIndeces.Add(firstNormal);
                            fileIndeces.Add(secondPosition);
                            fileIndeces.Add(secondTextureCoordinates);
                            fileIndeces.Add(secondNormal);
                            // Now include the new vertex
                            string[] indexReferences = parameters[i].Split('/');
                            if (indexReferences[0] == "")
                            {
                                throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath);
                            }
                            fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture));
                            if (indexReferences[1] != "")
                            {
                                fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture));
                            }
                            else
                            {
                                fileIndeces.Add(0);
                            }
                            if (indexReferences[2] != "")
                            {
                                fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture));
                            }
                            else
                            {
                                fileIndeces.Add(0);
                            }
                        }
                        break;

                    //// OLD VERSION OF THE FACE PARSING
                    //// NOTE! This does not yet triangulate faces
                    //// NOTE! This needs all possible values (position, texture mapping, and normal).
                    //for (int i = 1; i < parameters.Length; i++)
                    //{
                    //  string[] indexReferences = parameters[i].Split('/');
                    //  fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture));
                    //  if (indexReferences[1] != "")
                    //    fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture));
                    //  else
                    //    fileIndeces.Add(0);
                    //  if (indexReferences[2] != "")
                    //    fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture));
                    //  else
                    //    fileIndeces.Add(0);
                    //}
                    //break;

                    // End Current Mesh
                    case "7":
                        // Pull the final vertex order out of the indexed references
                        // Note, arrays start at 0 but the index references start at 1
                        float[] verteces = new float[fileIndeces.Count];
                        for (int i = 0; i < fileIndeces.Count; i += 3)
                        {
                            int index = (fileIndeces[i] - 1) * 3;
                            verteces[i]     = fileVerteces[index];
                            verteces[i + 1] = fileVerteces[index + 1];
                            verteces[i + 2] = fileVerteces[index + 2];
                        }

                        // Pull the final texture coordinates order out of the indexed references
                        // Note, arrays start at 0 but the index references start at 1
                        // Note, every other value needs to be inverse (not sure why but it works :P)
                        float[] textureCoordinates = new float[fileIndeces.Count / 3 * 2];
                        for (int i = 1; i < fileIndeces.Count; i += 3)
                        {
                            int index  = (fileIndeces[i] - 1) * 2;
                            int offset = (i - 1) / 3;
                            textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index];
                            textureCoordinates[i - offset]     = 1 - fileTextureCoordinates[(index + 1)];
                        }

                        // Pull the final normal order out of the indexed references
                        // Note, arrays start at 0 but the index references start at 1
                        float[] normals = new float[fileIndeces.Count];
                        for (int i = 2; i < fileIndeces.Count; i += 3)
                        {
                            int index = (fileIndeces[i] - 1) * 3;
                            normals[i - 2] = fileNormals[index];
                            normals[i - 1] = fileNormals[(index + 1)];
                            normals[i]     = fileNormals[(index + 2)];
                        }

                        int vertexBufferId;
                        if (verteces != null)
                        {
                            // Declare the buffer
                            GL.GenBuffers(1, out vertexBufferId);
                            // Select the new buffer
                            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId);
                            // Initialize the buffer values
                            GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw);
                            // Quick error checking
                            int bufferSize;
                            GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                            if (verteces.Length * sizeof(float) != bufferSize)
                            {
                                throw new StaticModelManagerException("Vertex array not uploaded correctly");
                            }
                            // Deselect the new buffer
                            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                        }
                        else
                        {
                            vertexBufferId = 0;
                        }

                        int textureCoordinateBufferId;
                        if (textureCoordinates != null)
                        {
                            // Declare the buffer
                            GL.GenBuffers(1, out textureCoordinateBufferId);
                            // Select the new buffer
                            GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId);
                            // Initialize the buffer values
                            GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw);
                            // Quick error checking
                            int bufferSize;
                            GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                            if (textureCoordinates.Length * sizeof(float) != bufferSize)
                            {
                                throw new StaticModelManagerException("TexCoord array not uploaded correctly");
                            }
                            // Deselect the new buffer
                            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                        }
                        else
                        {
                            textureCoordinateBufferId = 0;
                        }

                        int normalBufferId;
                        if (normals != null)
                        {
                            // Declare the buffer
                            GL.GenBuffers(1, out normalBufferId);
                            // Select the new buffer
                            GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId);
                            // Initialize the buffer values
                            GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw);
                            // Quick error checking
                            int bufferSize;
                            GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                            if (normals.Length * sizeof(float) != bufferSize)
                            {
                                throw new StaticModelManagerException("Normal array not uploaded correctly");
                            }
                            // Deselect the new buffer
                            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                        }
                        else
                        {
                            normalBufferId = 0;
                        }

                        meshes.Add(
                            new StaticMesh(
                                meshName,
                                staticModelId + "sub" + meshes.Count,
                                vertexBufferId,
                                0, // Obj files don't support vertex colors
                                textureCoordinateBufferId,
                                normalBufferId,
                                0, // I don't support an index buffer at this time
                                verteces.Length,
                                texture));
                        fileVerteces.Clear();
                        fileNormals.Clear();
                        fileTextureCoordinates.Clear();
                        fileIndeces.Clear();
                        texture = null;
                        break;
                    }
                }
            }
            return(new StaticModel(staticModelId, meshes));
        }
예제 #3
0
    /// <summary>DONT USE THIS FUNCTION!!! This is an experimental file type I may use in the future.</summary>
    public static StaticModel LoadSevenModelFromDisk(string staticModelId, string filePath)
    {
      // These are temporarily needed lists for storing the parsed data as you read it.
      List_Array<float> fileVerteces = new List_Array<float>(1000);
      List_Array<float> fileNormals = new List_Array<float>(1000);
      List_Array<float> fileTextureCoordinates = new List_Array<float>(1000);
      List_Array<int> fileIndeces = new List_Array<int>(1000);
      Texture texture = null;
      string meshName = "defaultMeshName";

      AvlTree<StaticMesh> meshes = new AvlTree_Linked<StaticMesh>(StaticMesh.CompareTo);

      // Lets read the file and handle each line separately for ".obj" files
      using (StreamReader reader = new StreamReader(filePath))
      {
        while (!reader.EndOfStream)
        {
          string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
          switch (parameters[0])
          {
            // MeshName
            case "m":
              meshName = parameters[1];
              break;

            // Texture
            case "t":
              if (!TextureManager.TextureExists(parameters[1]))
                TextureManager.LoadTexture(parameters[1], parameters[2]);
              texture = TextureManager.Get(parameters[1]);
              break;

            // Vertex
            case "v":
              fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
              fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
              fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture));
              break;

            // Texture Coordinate
            case "vt":
              fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
              fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
              break;

            // Normal
            case "vn":
              fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
              fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
              fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture));
              break;

            // Face
            case "f":
              // DEVELOPMENT NOTE: The following triangulation algorithm works, but it 
              // could be optimized beyond its current state.

              // The following variables are used for triangulation of a polygon
              // with greater than three verteces.
              int firstPosition, firstTextureCoordinates, firstNormal,
                secondPosition, secondTextureCoordinates, secondNormal;
              if (parameters.Length > 3)
              {
                // First Vertex (we have to store it this way for possible triangulation)
                string[] indexReferences = parameters[1].Split('/');
                if (indexReferences[0] == "")
                  throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath);
                firstPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture);
                if (indexReferences[1] != "")
                  firstTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture);
                else
                  firstTextureCoordinates = 0;
                if (indexReferences[2] != "")
                  firstNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture);
                else
                  firstNormal = 0;

                // Second Vertex (we have to store it this way for possible triangulation)
                indexReferences = parameters[2].Split('/');
                if (indexReferences[0] == "")
                  throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath);
                secondPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture);
                if (indexReferences[1] != "")
                  secondTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture);
                else
                  secondTextureCoordinates = 0;
                if (indexReferences[2] != "")
                  secondNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture);
                else
                  secondNormal = 0;
              }
              else
                throw new StaticModelManagerException("ERROR: obj file corrupted:" + filePath);

              // Verteces past the first two
              for (int i = 3; i < parameters.Length; i++)
              {
                // Triangulate using the first two verteces
                fileIndeces.Add(firstPosition);
                fileIndeces.Add(firstTextureCoordinates);
                fileIndeces.Add(firstNormal);
                fileIndeces.Add(secondPosition);
                fileIndeces.Add(secondTextureCoordinates);
                fileIndeces.Add(secondNormal);
                // Now include the new vertex
                string[] indexReferences = parameters[i].Split('/');
                if (indexReferences[0] == "")
                  throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath);
                fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture));
                if (indexReferences[1] != "")
                  fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture));
                else
                  fileIndeces.Add(0);
                if (indexReferences[2] != "")
                  fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture));
                else
                  fileIndeces.Add(0);
              }
              break;

              //// OLD VERSION OF THE FACE PARSING
              //// NOTE! This does not yet triangulate faces
              //// NOTE! This needs all possible values (position, texture mapping, and normal).
              //for (int i = 1; i < parameters.Length; i++)
              //{
              //  string[] indexReferences = parameters[i].Split('/');
              //  fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture));
              //  if (indexReferences[1] != "")
              //    fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture));
              //  else
              //    fileIndeces.Add(0);
              //  if (indexReferences[2] != "")
              //    fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture));
              //  else
              //    fileIndeces.Add(0);
              //}
              //break;

            // End Current Mesh
            case "7":
              // Pull the final vertex order out of the indexed references
              // Note, arrays start at 0 but the index references start at 1
              float[] verteces = new float[fileIndeces.Count];
              for (int i = 0; i < fileIndeces.Count; i += 3)
              {
                int index = (fileIndeces[i] - 1) * 3;
                verteces[i] = fileVerteces[index];
                verteces[i + 1] = fileVerteces[index + 1];
                verteces[i + 2] = fileVerteces[index + 2];
              }

              // Pull the final texture coordinates order out of the indexed references
              // Note, arrays start at 0 but the index references start at 1
              // Note, every other value needs to be inverse (not sure why but it works :P)
              float[] textureCoordinates = new float[fileIndeces.Count / 3 * 2];
              for (int i = 1; i < fileIndeces.Count; i += 3)
              {
                int index = (fileIndeces[i] - 1) * 2;
                int offset = (i - 1) / 3;
                textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index];
                textureCoordinates[i - offset] = 1 - fileTextureCoordinates[(index + 1)];
              }

              // Pull the final normal order out of the indexed references
              // Note, arrays start at 0 but the index references start at 1
              float[] normals = new float[fileIndeces.Count];
              for (int i = 2; i < fileIndeces.Count; i += 3)
              {
                int index = (fileIndeces[i] - 1) * 3;
                normals[i - 2] = fileNormals[index];
                normals[i - 1] = fileNormals[(index + 1)];
                normals[i] = fileNormals[(index + 2)];
              }

              int vertexBufferId;
              if (verteces != null)
              {
                // Declare the buffer
                GL.GenBuffers(1, out vertexBufferId);
                // Select the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId);
                // Initialize the buffer values
                GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw);
                // Quick error checking
                int bufferSize;
                GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                if (verteces.Length * sizeof(float) != bufferSize)
                  throw new StaticModelManagerException("Vertex array not uploaded correctly");
                // Deselect the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
              }
              else { vertexBufferId = 0; }

              int textureCoordinateBufferId;
              if (textureCoordinates != null)
              {
                // Declare the buffer
                GL.GenBuffers(1, out textureCoordinateBufferId);
                // Select the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId);
                // Initialize the buffer values
                GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw);
                // Quick error checking
                int bufferSize;
                GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                if (textureCoordinates.Length * sizeof(float) != bufferSize)
                  throw new StaticModelManagerException("TexCoord array not uploaded correctly");
                // Deselect the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
              }
              else { textureCoordinateBufferId = 0; }

              int normalBufferId;
              if (normals != null)
              {
                // Declare the buffer
                GL.GenBuffers(1, out normalBufferId);
                // Select the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId);
                // Initialize the buffer values
                GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw);
                // Quick error checking
                int bufferSize;
                GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                if (normals.Length * sizeof(float) != bufferSize)
                  throw new StaticModelManagerException("Normal array not uploaded correctly");
                // Deselect the new buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
              }
              else { normalBufferId = 0; }

              meshes.Add(
                  new StaticMesh(
                  meshName,
                  staticModelId + "sub" + meshes.Count,
                  vertexBufferId,
                  0, // Obj files don't support vertex colors
                  textureCoordinateBufferId,
                  normalBufferId,
                  0, // I don't support an index buffer at this time
                  verteces.Length,
                  texture));
              fileVerteces.Clear();
              fileNormals.Clear();
              fileTextureCoordinates.Clear();
              fileIndeces.Clear();
              texture = null;
              break;
          }
        }
      }
      return new StaticModel(staticModelId, meshes);
    }
예제 #4
0
    private static StaticMesh LoadObj(string staticMeshId, string filePath)
    {
      // These are temporarily needed lists for storing the parsed data as you read it.
      // Its better to use "ListArrays" vs "Lists" because they will be accessed by indeces
      // by the faces of the obj file.
      List_Array<float> fileVerteces = new List_Array<float>(10000);
      List_Array<float> fileNormals = new List_Array<float>(10000);
      List_Array<float> fileTextureCoordinates = new List_Array<float>(10000);
      List_Array<int> fileIndeces = new List_Array<int>(10000);

      // Obj files are not required to include texture coordinates or normals
      bool hasTextureCoordinates = true;
      bool hasNormals = true;

      // Lets read the file and handle each line separately for ".obj" files
      using (StreamReader reader = new StreamReader(filePath))
      {
        int lineNumber = 1;
        while (!reader.EndOfStream)
        {
          try
          {
            string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            switch (parameters[0])
            {
              // Vertex
              case "v":
                fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture));
                break;

              // Texture Coordinate
              case "vt":
                fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                break;

              // Normal
              case "vn":
                fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture));
                fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture));
                fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture));
                break;

              // Face
              case "f":
                //if (parameters.Length < 4)
                //  throw new StaticModelManagerException("obj file corrupt.");
                int first = fileIndeces.Count;
                for (int i = 1; i < parameters.Length; i++)
                {
                  if (i > 3)
                  {
                    // Triangulate using the previous two verteces
                    // NOTE: THIS MAY BE INCORRECT! I COULD NOT YET FIND DOCUMENTATION
                    // ON THE TRIANGULATION DONE BY BLENDER (WORKS FOR QUADS AT LEAST)

                    //// Last two (triangle strip)
                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                    //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);

                    // First then previous (triangle fan)
                    fileIndeces.Add(fileIndeces[first]);
                    fileIndeces.Add(fileIndeces[first + 1]);
                    fileIndeces.Add(fileIndeces[first + 2]);
                    fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                    fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                    fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]);
                  }

                  // Now include the new vertex
                  string[] indexReferences = parameters[i].Split('/');
                  //if (indexReferences[0] == "")
                  //  throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition):" + filePath);
                  fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture));

                  if (hasNormals && indexReferences.Length < 3)
                    hasNormals = false;
                  if (hasTextureCoordinates && (indexReferences.Length < 2 || indexReferences[1] == ""))
                    hasTextureCoordinates = false;

                  if (hasTextureCoordinates && indexReferences[1] != "")
                    fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture));
                  else
                    fileIndeces.Add(0);

                  if (hasNormals && indexReferences[2] != "")
                    fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture));
                  else
                    fileIndeces.Add(0);
                }
                break;
            }
          }
          catch
          {
            string[] pathSplit = filePath.Split('\\');
            throw new StaticModelManagerException("Could not load model " + pathSplit[pathSplit.Length - 1] +
              ". There is a corruption on line " + lineNumber +".");
          }
          lineNumber++;
        }
      }

      // Pull the final vertex order out of the indexed references
      // Note, arrays start at 0 but the index references start at 1
      float[] verteces = new float[fileIndeces.Count];
      for (int i = 0; i < fileIndeces.Count; i += 3)
      {
        int index = (fileIndeces[i] - 1) * 3;
        verteces[i] = fileVerteces[index];
        verteces[i + 1] = fileVerteces[index + 1];
        verteces[i + 2] = fileVerteces[index + 2];
      }

      float[] textureCoordinates = null;
      if (hasTextureCoordinates)
      {
        // Pull the final texture coordinates order out of the indexed references
        // Note, arrays start at 0 but the index references start at 1
        // Note, every other value needs to be inverse (not sure why but it works :P)
        textureCoordinates = new float[fileIndeces.Count / 3 * 2];
        for (int i = 1; i < fileIndeces.Count; i += 3)
        {
          int index = (fileIndeces[i] - 1) * 2;
          int offset = (i - 1) / 3;
          textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index];
          textureCoordinates[i - offset] = 1 - fileTextureCoordinates[(index + 1)];
        }
      }

      float[] normals = null;
      if (hasNormals)
      {
        // Pull the final normal order out of the indexed references
        // Note, arrays start at 0 but the index references start at 1
        normals = new float[fileIndeces.Count];
        for (int i = 2; i < fileIndeces.Count; i += 3)
        {
          int index = (fileIndeces[i] - 1) * 3;
          normals[i - 2] = fileNormals[index];
          normals[i - 1] = fileNormals[(index + 1)];
          normals[i] = fileNormals[(index + 2)];
        }
      }

      int vertexBufferId;
      if (verteces != null)
      {
        // Make the vertex buffer on the GPU
        GL.GenBuffers(1, out vertexBufferId);
        GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId);
        GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw);
        int bufferSize;
        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
        if (verteces.Length * sizeof(float) != bufferSize)
          throw new StaticModelManagerException("Vertex array not uploaded correctly");
        // Deselect the new buffer
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
      }
      else { vertexBufferId = 0; }

      int textureCoordinateBufferId;
      if (hasTextureCoordinates && textureCoordinates != null)
      {
        // Make the texture coordinate buffer on the GPU
        GL.GenBuffers(1, out textureCoordinateBufferId);
        GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId);
        GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw);
        int bufferSize;
        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
        if (textureCoordinates.Length * sizeof(float) != bufferSize)
          throw new StaticModelManagerException("TexCoord array not uploaded correctly");
        // Deselect the new buffer
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
      }
      else { textureCoordinateBufferId = 0; }

      int normalBufferId;
      if (hasNormals && normals != null)
      {
        // Make the normal buffer on the GPU
        GL.GenBuffers(1, out normalBufferId);
        GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId);
        GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw);
        int bufferSize;
        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
        if (normals.Length * sizeof(float) != bufferSize)
          throw new StaticModelManagerException("Normal array not uploaded correctly");
        // Deselect the new buffer
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
      }
      else { normalBufferId = 0; }

      return new StaticMesh(
        filePath,
        staticMeshId,
        vertexBufferId,
        0, // Obj files don't support vertex colors
        textureCoordinateBufferId,
        normalBufferId,
        0, // I don't support an index buffer at this time
        verteces.Length,
        null);
    }
예제 #5
0
 internal void AddKearning(int followingCharacter, int ammount)
 {
     _kearnings.Add(new Link <int, int>(followingCharacter, ammount));
 }
예제 #6
0
    public static void LoadFontFile(string id, string filePath, string textureLocations)
    {
      List_Array<CharacterSprite> characters = new List_Array<CharacterSprite>(255);
      List_Array<string> textures = new List_Array<string>(1);
      int lineHeight = -1, fontBase = int.MinValue;
      using (StreamReader reader = new StreamReader(filePath))
      {
        int lineNumber = 1;
        while (!reader.EndOfStream)
        {
          string line = reader.ReadLine();
          string[] parameters = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
          switch (parameters[0].ToLower())
          {
            case "common":
              for (int i = 1; i < parameters.Length; i++)
              {
                string[] attributes = parameters[i].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                switch (attributes[0].ToLower())
                {
                  case "lineheight":
                    if (!int.TryParse(attributes[1], out lineHeight))
                      throw new TextManagerException("The line height value of the font file is corrupt on line " + lineNumber + ".");
                    break;

                  case "base":
                    if (!int.TryParse(attributes[1], out fontBase))
                      throw new TextManagerException("The base value of the font file is corrupt on line " + lineNumber + ".");
                    break;
                }
              }
              break;

            case "page":
              string[] textureFile = parameters[2].Split("\"".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
              try { TextureManager.LoadTexture(textureFile[1], textureLocations + textureFile[1]); }
              catch { throw new TextManagerException("The font file is using a non-supported image file on line " + lineNumber + "."); }
              textures.Add(textureFile[1]);
              break;

            case "char":
              int charId = -1,
                x = -1, y = -1,
                width = -1, height = -1,
                xOffset = int.MinValue, yOffset = int.MinValue,
                xAdvance = -1,
                page = -1;
              // channel=-1;

              // Lets get all the attributes of the character
              for (int i = 1; i < parameters.Length; i++)
              {
                string[] attribute = parameters[i].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                if (attribute.Length < 2)
                  throw new TextManagerException("Font file has a corrupted character attribute on line " + lineNumber + ".");
                switch (attribute[0].ToLower())
                {
                  case "id":
                    if (!int.TryParse(attribute[1], out charId))
                      throw new TextManagerException("An id value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  case "x":
                    if (!int.TryParse(attribute[1], out x))
                      throw new TextManagerException("A x value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  case "y":
                    if (!int.TryParse(attribute[1], out y))
                      throw new TextManagerException("A y value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  case "width":
                    if (!int.TryParse(attribute[1], out width))
                      throw new TextManagerException("A width value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  case "height":
                    if (!int.TryParse(attribute[1], out height))
                      throw new TextManagerException("A height value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  case "xoffset":
                    if (!int.TryParse(attribute[1], out xOffset))
                      throw new TextManagerException("A xoffset value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  case "yoffset":
                    if (!int.TryParse(attribute[1], out yOffset))
                      throw new TextManagerException("A yoffset value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  case "xadvance":
                    if (!int.TryParse(attribute[1], out xAdvance))
                      throw new TextManagerException("A xadvance value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  case "page":
                    if (!int.TryParse(attribute[1], out page))
                      throw new TextManagerException("A page value in font file is corrupted on line " + lineNumber + ".");
                    break;
                  //// This check is most likely unnecessary, an error will be thrown during image loading attempt.
                  //case "chnl":
                  //  if (!int.TryParse(attribute[1], out channel))
                  //    throw new TextManagerException("A chnl value in font file is corrupted on line " + lineNumber + ".");
                  //  if (channel != 15)
                  //    throw new TextManagerException("The font file is using a non-supported image file.");
                }
              }

              // Make sure all the necessary values were imported and are valid
              if (charId == -1)
                throw new TextManagerException("Font file is corrupt/missing on a char id on line " + lineNumber + ".");
              if (x < 0)
                throw new TextManagerException("Font file has corrupt/missing on x value on line " + lineNumber + ".");
              if (y < 0)
                throw new TextManagerException("Font file has a corrupt/missing y value on line " + lineNumber + ".");
              if (width < 0)
                throw new TextManagerException("Font file has a corrupt/missing width value on line " + lineNumber + ".");
              if (height == -1)
                throw new TextManagerException("Font file has a corrupt/missing height value on line " + lineNumber + ".");
              if (xOffset == int.MinValue)
                throw new TextManagerException("Font file is missing a xoffset value on line " + lineNumber + ".");
              if (yOffset == int.MinValue)
                throw new TextManagerException("Font file is missing a yoffset value on line " + lineNumber + ".");
              if (xAdvance < 0)
                throw new TextManagerException("Font file has a corrupt/missing xadvance value on line " + lineNumber + ".");
              if (page < 0 || page > textures.Count)
                throw new TextManagerException("Font file has a corrupt/missing page value on line " + lineNumber + ".");
              //// This check is most likely unnecessary, an error will be thrown during image loading attempt.
              //if (channel == -1)
              //  throw new TextManagerException("Font file is missing a channel value on line " + lineNumber + ".");

              characters.Add(
                new CharacterSprite(
                  TextureManager.Get(textures[page]),
                  charId,
                  xAdvance,
                  x, y,
                  width, height,
                  xOffset, yOffset));
              break;

            #region OLD CODE (I'll delete this when I'm done debugging the newer version)
            // THIS WAS MY INITIAL PARSER JUST TO GET THINGS WORKING
            //  characters.Add(new CharacterSprite(
            //    // Texture
            //    TextureManager.Get(textures[int.Parse(parameters[9].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture)]),
            //    // Id
            //    int.Parse(parameters[1].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
            //    // X Advance
            //    int.Parse(parameters[8].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
            //    // X
            //    int.Parse(parameters[2].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
            //    // Y
            //    int.Parse(parameters[3].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
            //    // Width
            //    int.Parse(parameters[4].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
            //    // Height
            //    int.Parse(parameters[5].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
            //    // X Offset
            //    int.Parse(parameters[6].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
            //    // Y Offset
            //    int.Parse(parameters[7].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture)));
            //  break;
            //case "kerning":
            //  int first = int.Parse(parameters[1].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture);
            //  for (int i = 0; i < characters.Count; i++)
            //    if (characters[i].Id == first)
            //      characters[i].AddKearning(
            //        int.Parse(parameters[2].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
            //        int.Parse(parameters[3].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture));
            //    break;
            #endregion
          }
          lineNumber++;
        }
      }
      if (lineHeight < 0)
        throw new TextManagerException("Font file has a corrupt/missing line height value.");
      _fontDatabase.Add(new Font(id, lineHeight, fontBase, characters));
      string[] pathSplit = filePath.Split('\\');
      Output.WriteLine("Font file loaded: \"" + pathSplit[pathSplit.Length - 1] + "\".");
    }
예제 #7
0
        public static void LoadFontFile(string id, string filePath, string textureLocations)
        {
            List_Array <CharacterSprite> characters = new List_Array <CharacterSprite>(255);
            List_Array <string>          textures = new List_Array <string>(1);
            int lineHeight = -1, fontBase = int.MinValue;

            using (StreamReader reader = new StreamReader(filePath))
            {
                int lineNumber = 1;
                while (!reader.EndOfStream)
                {
                    string   line       = reader.ReadLine();
                    string[] parameters = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    switch (parameters[0].ToLower())
                    {
                    case "common":
                        for (int i = 1; i < parameters.Length; i++)
                        {
                            string[] attributes = parameters[i].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                            switch (attributes[0].ToLower())
                            {
                            case "lineheight":
                                if (!int.TryParse(attributes[1], out lineHeight))
                                {
                                    throw new TextManagerException("The line height value of the font file is corrupt on line " + lineNumber + ".");
                                }
                                break;

                            case "base":
                                if (!int.TryParse(attributes[1], out fontBase))
                                {
                                    throw new TextManagerException("The base value of the font file is corrupt on line " + lineNumber + ".");
                                }
                                break;
                            }
                        }
                        break;

                    case "page":
                        string[] textureFile = parameters[2].Split("\"".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        try { TextureManager.LoadTexture(textureFile[1], textureLocations + textureFile[1]); }
                        catch { throw new TextManagerException("The font file is using a non-supported image file on line " + lineNumber + "."); }
                        textures.Add(textureFile[1]);
                        break;

                    case "char":
                        int charId = -1,
                            x = -1, y = -1,
                            width = -1, height = -1,
                            xOffset = int.MinValue, yOffset = int.MinValue,
                            xAdvance = -1,
                            page     = -1;
                        // channel=-1;

                        // Lets get all the attributes of the character
                        for (int i = 1; i < parameters.Length; i++)
                        {
                            string[] attribute = parameters[i].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                            if (attribute.Length < 2)
                            {
                                throw new TextManagerException("Font file has a corrupted character attribute on line " + lineNumber + ".");
                            }
                            switch (attribute[0].ToLower())
                            {
                            case "id":
                                if (!int.TryParse(attribute[1], out charId))
                                {
                                    throw new TextManagerException("An id value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;

                            case "x":
                                if (!int.TryParse(attribute[1], out x))
                                {
                                    throw new TextManagerException("A x value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;

                            case "y":
                                if (!int.TryParse(attribute[1], out y))
                                {
                                    throw new TextManagerException("A y value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;

                            case "width":
                                if (!int.TryParse(attribute[1], out width))
                                {
                                    throw new TextManagerException("A width value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;

                            case "height":
                                if (!int.TryParse(attribute[1], out height))
                                {
                                    throw new TextManagerException("A height value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;

                            case "xoffset":
                                if (!int.TryParse(attribute[1], out xOffset))
                                {
                                    throw new TextManagerException("A xoffset value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;

                            case "yoffset":
                                if (!int.TryParse(attribute[1], out yOffset))
                                {
                                    throw new TextManagerException("A yoffset value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;

                            case "xadvance":
                                if (!int.TryParse(attribute[1], out xAdvance))
                                {
                                    throw new TextManagerException("A xadvance value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;

                            case "page":
                                if (!int.TryParse(attribute[1], out page))
                                {
                                    throw new TextManagerException("A page value in font file is corrupted on line " + lineNumber + ".");
                                }
                                break;
                                //// This check is most likely unnecessary, an error will be thrown during image loading attempt.
                                //case "chnl":
                                //  if (!int.TryParse(attribute[1], out channel))
                                //    throw new TextManagerException("A chnl value in font file is corrupted on line " + lineNumber + ".");
                                //  if (channel != 15)
                                //    throw new TextManagerException("The font file is using a non-supported image file.");
                            }
                        }

                        // Make sure all the necessary values were imported and are valid
                        if (charId == -1)
                        {
                            throw new TextManagerException("Font file is corrupt/missing on a char id on line " + lineNumber + ".");
                        }
                        if (x < 0)
                        {
                            throw new TextManagerException("Font file has corrupt/missing on x value on line " + lineNumber + ".");
                        }
                        if (y < 0)
                        {
                            throw new TextManagerException("Font file has a corrupt/missing y value on line " + lineNumber + ".");
                        }
                        if (width < 0)
                        {
                            throw new TextManagerException("Font file has a corrupt/missing width value on line " + lineNumber + ".");
                        }
                        if (height == -1)
                        {
                            throw new TextManagerException("Font file has a corrupt/missing height value on line " + lineNumber + ".");
                        }
                        if (xOffset == int.MinValue)
                        {
                            throw new TextManagerException("Font file is missing a xoffset value on line " + lineNumber + ".");
                        }
                        if (yOffset == int.MinValue)
                        {
                            throw new TextManagerException("Font file is missing a yoffset value on line " + lineNumber + ".");
                        }
                        if (xAdvance < 0)
                        {
                            throw new TextManagerException("Font file has a corrupt/missing xadvance value on line " + lineNumber + ".");
                        }
                        if (page < 0 || page > textures.Count)
                        {
                            throw new TextManagerException("Font file has a corrupt/missing page value on line " + lineNumber + ".");
                        }
                        //// This check is most likely unnecessary, an error will be thrown during image loading attempt.
                        //if (channel == -1)
                        //  throw new TextManagerException("Font file is missing a channel value on line " + lineNumber + ".");

                        characters.Add(
                            new CharacterSprite(
                                TextureManager.Get(textures[page]),
                                charId,
                                xAdvance,
                                x, y,
                                width, height,
                                xOffset, yOffset));
                        break;

                        #region OLD CODE (I'll delete this when I'm done debugging the newer version)
                        // THIS WAS MY INITIAL PARSER JUST TO GET THINGS WORKING
                        //  characters.Add(new CharacterSprite(
                        //    // Texture
                        //    TextureManager.Get(textures[int.Parse(parameters[9].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture)]),
                        //    // Id
                        //    int.Parse(parameters[1].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
                        //    // X Advance
                        //    int.Parse(parameters[8].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
                        //    // X
                        //    int.Parse(parameters[2].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
                        //    // Y
                        //    int.Parse(parameters[3].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
                        //    // Width
                        //    int.Parse(parameters[4].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
                        //    // Height
                        //    int.Parse(parameters[5].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
                        //    // X Offset
                        //    int.Parse(parameters[6].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
                        //    // Y Offset
                        //    int.Parse(parameters[7].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture)));
                        //  break;
                        //case "kerning":
                        //  int first = int.Parse(parameters[1].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture);
                        //  for (int i = 0; i < characters.Count; i++)
                        //    if (characters[i].Id == first)
                        //      characters[i].AddKearning(
                        //        int.Parse(parameters[2].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture),
                        //        int.Parse(parameters[3].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture));
                        //    break;
                        #endregion
                    }
                    lineNumber++;
                }
            }
            if (lineHeight < 0)
            {
                throw new TextManagerException("Font file has a corrupt/missing line height value.");
            }
            _fontDatabase.Add(new Font(id, lineHeight, fontBase, characters));
            string[] pathSplit = filePath.Split('\\');
            Output.WriteLine("Font file loaded: \"" + pathSplit[pathSplit.Length - 1] + "\".");
        }