Example #1
0
        public int LoadFromStream(Stream stream)
        {
            if (stream == null)
                return 0;

            ImageImporter imageImporter = new ImageImporter();

            Image image = imageImporter.LoadImageFromStream(stream);

            GCHandle imageDataGCHandle = GCHandle.Alloc(image.GetImageData(0).Data, GCHandleType.Pinned);
            IntPtr imageDataIntPtr = imageDataGCHandle.AddrOfPinnedObject();

            int glTextureHandle = GL.GenTexture();

            GL.Enable(EnableCap.Texture2D);
            GL.BindTexture(TextureTarget.Texture2D, glTextureHandle);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, image.Width, image.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, imageDataIntPtr);
            GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.Disable(EnableCap.Texture2D);

            imageDataGCHandle.Free();

            textures.Add(glTextureHandle);

            return glTextureHandle;
        }
Example #2
0
        public Bitmap getShopImage(string surface)
        {
            Bitmap sourceBitmap = Properties.Resources.blank;
            string key          = surface.ToLower();

            if (images.ContainsKey(key))
            {
                return(images[key]);
            }

            if (!File.Exists(surface))
            {
                return(sourceBitmap);
            }
            try
            {
                using (DevIL.ImageImporter imImport = new DevIL.ImageImporter())
                {
                    sourceBitmap = images[key] = LoadImage(imImport, new MemoryStream(File.ReadAllBytes(surface)));
                    return(sourceBitmap);
                }
            }
            catch { }
            return(sourceBitmap);
        }
Example #3
0
        protected void SetFromStream(Stream stream)
        {
            // try loading using standard .net first
            try
            {
                // We need to copy the stream over to a new, in-memory bitmap to
                // avoid keeping the input stream open.
                // See http://support.microsoft.com/kb/814675/en-us
                using (var img = Image.FromStream(stream))
                {
                    _image = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);

                    using (var gfx = Graphics.FromImage(_image))
                    {
                        gfx.DrawImage(img, 0, 0, img.Width, img.Height);
                    }

                    _result = LoadResult.Good;
                }
            }
            catch (Exception)
            {
                // if this fails, load using DevIL
                using (var imp = new DevIL.ImageImporter())
                {
                    try
                    {
                        using (var devilImage = imp.LoadImageFromStream(stream))
                        {
                            devilImage.Bind();

                            var info   = DevIL.Unmanaged.IL.GetImageInfo();
                            var bitmap = new Bitmap(info.Width, info.Height, PixelFormat.Format32bppArgb);
                            var rect   = new Rectangle(0, 0, info.Width, info.Height);
                            var data   = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

                            DevIL.Unmanaged.IL.CopyPixels(0, 0, 0, info.Width, info.Height, 1, DataFormat.BGRA, DataType.UnsignedByte, data.Scan0);

                            bitmap.UnlockBits(data);
                            _image  = bitmap;
                            _result = LoadResult.Good;
                            _image.RotateFlip(RotateFlipType.RotateNoneFlipY);
                        }
                    }
                    catch (Exception)
                    {
                        // TODO any other viable fall back image loaders?
                        _result = LoadResult.UnknownFileFormat;
                    }
                }
            }
        }
Example #4
0
        public static System.Drawing.Image LoadImageFromStream(Stream stream)
        {
            ImageImporter importer = new ImageImporter();
            DevIL.Image img = importer.LoadImageFromStream(stream);

            DevIL.Unmanaged.ImageInfo imageInfo = img.GetImageInfo();
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imageInfo.Width, imageInfo.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(0, 0, imageInfo.Width, imageInfo.Height);
            System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(rectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            DevIL.Unmanaged.IL.CopyPixels(0, 0, 0, imageInfo.Width, imageInfo.Height, 1, DataFormat.BGRA, DevIL.DataType.UnsignedByte, bitmapData.Scan0);

            bitmap.UnlockBits(bitmapData);

            return (System.Drawing.Image)bitmap;
        }
Example #5
0
        private void InitDevIL() {
            m_importer = new ImageImporter();
            m_exporter = new ImageExporter();
            ImageState state = new ImageState();
            state.AbsoluteFormat = DataFormat.BGRA;
            state.AbsoluteDataType = DataType.UnsignedByte;
            state.AbsoluteOrigin = OriginLocation.UpperLeft;
            state.Apply();

            CompressionState comp = new CompressionState();
            comp.KeepDxtcData = true;
            comp.Apply();

            SaveState sstate = new SaveState();
            sstate.OverwriteExistingFile = true;
            sstate.Apply();
        }
Example #6
0
 public Bitmap LoadImage(DevIL.ImageImporter ImImport, MemoryStream mStream, int width = 128, int height = 128)
 {
     try
     {
         Bitmap img2 = null;
         using (DevIL.Image IconImg = ImImport.LoadImageFromStream(mStream))
         {
             IconImg.Bind();
             using (var img = new Bitmap(IconImg.Width, IconImg.Height, PixelFormat.Format32bppArgb))
             {
                 Rectangle  rect = new Rectangle(0, 0, IconImg.Width, IconImg.Height);
                 BitmapData data = img.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                 DevIL.Unmanaged.IL.CopyPixels(0, 0, 0, IconImg.Width, IconImg.Height, 1, DevIL.DataFormat.BGRA, DevIL.DataType.UnsignedByte, data.Scan0);
                 img.UnlockBits(data);
                 img2 = (Bitmap)img.Clone();
             }
         }
         return(img2);
     }
     catch
     {
         return(new Bitmap(width, height));
     }
 }
        public static List<Texture> LoadFromFile(string rootPath ,string filePath)
        {
            ImageImporter importer = new ImageImporter();
            ImageExporter exporter = new ImageExporter();
            Image image;
            List<Texture> textures = new List<Texture>();
            string[] fps = filePath.Split('*');
            string fp;
            for (int i = 0; i < fps.Length; i++)
            {
                fp = rootPath + fps[i];
                image = importer.LoadImage(fp);

                if (Path.GetExtension(fp) != ".tga" && Path.GetExtension(fp) != ".png")
                {
                    if (!File.Exists(fp.Replace(Path.GetExtension(fp), ".tga")))
                        exporter.SaveImage(image, ImageType.Tga, fp.Replace(Path.GetExtension(fp), ".tga"));
                    image = importer.LoadImage(fp.Replace(Path.GetExtension(fp), ".tga"));
                }

                //image.Bind();
                //var info = DevIL.Unmanaged.IL.GetImageInfo();
                //var bitmap = new System.Drawing.Bitmap(info.Width, info.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                //var rect = new System.Drawing.Rectangle(0, 0, info.Width, info.Height);
                //var data = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                //DevIL.Unmanaged.IL.CopyPixels(0, 0, 0, info.Width, info.Height, info.Depth, DataFormat.BGRA, DataType.UnsignedByte);
                //bitmap.UnlockBits(data);
                //var converter = new System.Drawing.ImageConverter();
                //var test = converter.ConvertTo(bitmap, typeof(byte[]));
                //var raw = (byte[])converter.ConvertTo(bitmap, typeof(byte[]));

                textures.Add(new Texture(image, fp));
            }
            return textures;
        }
Example #8
0
        private static void exportModelAsOBJToDirectory(Model model, string directory, ExportOptions options)
        {
            //TODO: Figure out what to do with non-version 4 models.
            if (model != null && model.Version != 4)
            {
                return;
            }

            NumberFormatInfo format = new NumberFormatInfo();
            format.NumberDecimalSeparator = ".";

            if (options.Package)
            {
                try
                {
                    DirectoryInfo directoryInfo = Directory.CreateDirectory(directory + @"\" + Path.GetFileNameWithoutExtension(model.Name));
                    directory = directoryInfo.FullName;
                }
                catch (Exception) { }
            }

            if (options.Textures)
            {
                ImageImporter imageImporter = new ImageImporter();
                ImageExporter imageExporter = new ImageExporter();

                foreach(String textureString in model.TextureStrings)
                {
                    MemoryStream textureMemoryStream = AssetManager.Instance.CreateAssetMemoryStreamByName(textureString);

                    if(textureMemoryStream == null)
                        continue;

                    Image textureImage = imageImporter.LoadImageFromStream(textureMemoryStream);

                    if(textureImage == null)
                        continue;

                    imageExporter.SaveImage(textureImage, options.TextureFormat.ImageType, directory + @"\" + Path.GetFileNameWithoutExtension(textureString) + @"." + options.TextureFormat.Extension);
                }
            }

            String path = directory + @"\" + Path.GetFileNameWithoutExtension(model.Name) + ".obj";

            FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write);
            StreamWriter streamWriter = new StreamWriter(fileStream);

            for (Int32 i = 0; i < model.Meshes.Length; ++i)
            {
                Mesh mesh = model.Meshes[i];

                MaterialDefinition materialDefinition = MaterialDefinitionManager.Instance.MaterialDefinitions[model.Materials[(Int32)mesh.MaterialIndex].MaterialDefinitionHash];
                VertexLayout vertexLayout = MaterialDefinitionManager.Instance.VertexLayouts[materialDefinition.DrawStyles[0].VertexLayoutNameHash];

                //position
                VertexLayout.Entry.DataTypes positionDataType;
                Int32 positionOffset;
                Int32 positionStreamIndex;

                vertexLayout.GetEntryInfoFromDataUsageAndUsageIndex(VertexLayout.Entry.DataUsages.Position, 0, out positionDataType, out positionStreamIndex, out positionOffset);

                Mesh.VertexStream positionStream = mesh.VertexStreams[positionStreamIndex];

                for (Int32 j = 0; j < mesh.VertexCount; ++j)
                {
                    Vector3 position = readVector3(options, positionOffset, positionStream, j);

                    position.X *= options.Scale.X;
                    position.Y *= options.Scale.Y;
                    position.Z *= options.Scale.Z;

                    streamWriter.WriteLine("v " + position.X.ToString(format) + " " + position.Y.ToString(format) + " " + position.Z.ToString(format));
                }

                //texture coordinates
                if (options.TextureCoordinates)
                {
                    VertexLayout.Entry.DataTypes texCoord0DataType;
                    Int32 texCoord0Offset = 0;
                    Int32 texCoord0StreamIndex = 0;

                    Boolean texCoord0Present = vertexLayout.GetEntryInfoFromDataUsageAndUsageIndex(VertexLayout.Entry.DataUsages.Texcoord, 0, out texCoord0DataType, out texCoord0StreamIndex, out texCoord0Offset);

                    if (texCoord0Present)
                    {
                        Mesh.VertexStream texCoord0Stream = mesh.VertexStreams[texCoord0StreamIndex];

                        for (Int32 j = 0; j < mesh.VertexCount; ++j)
                        {
                            Vector2 texCoord;

                            switch (texCoord0DataType)
                            {
                                case VertexLayout.Entry.DataTypes.Float2:
                                    texCoord.X = BitConverter.ToSingle(texCoord0Stream.Data, (j * texCoord0Stream.BytesPerVertex) + 0);
                                    texCoord.Y = 1.0f - BitConverter.ToSingle(texCoord0Stream.Data, (j * texCoord0Stream.BytesPerVertex) + 4);
                                    break;
                                case VertexLayout.Entry.DataTypes.float16_2:
                                    texCoord.X = Half.FromBytes(texCoord0Stream.Data, (j * texCoord0Stream.BytesPerVertex) + texCoord0Offset + 0).ToSingle();
                                    texCoord.Y = 1.0f - Half.FromBytes(texCoord0Stream.Data, (j * texCoord0Stream.BytesPerVertex) + texCoord0Offset + 2).ToSingle();
                                    break;
                                default:
                                    texCoord.X = 0;
                                    texCoord.Y = 0;
                                    break;
                            }

                            streamWriter.WriteLine("vt " + texCoord.X.ToString(format) + " " + texCoord.Y.ToString(format));
                        }
                    }
                }
            }

            //faces
            UInt32 vertexCount = 0;

            for (Int32 i = 0; i < model.Meshes.Length; ++i)
            {
                Mesh mesh = model.Meshes[i];

                streamWriter.WriteLine("g Mesh" + i);

                for (Int32 j = 0; j < mesh.IndexCount; j += 3)
                {
                    UInt32 index0, index1, index2;

                    switch (mesh.IndexSize)
                    {
                        case 2:
                            index0 = vertexCount + BitConverter.ToUInt16(mesh.IndexData, (j * 2) + 0) + 1;
                            index1 = vertexCount + BitConverter.ToUInt16(mesh.IndexData, (j * 2) + 2) + 1;
                            index2 = vertexCount + BitConverter.ToUInt16(mesh.IndexData, (j * 2) + 4) + 1;
                            break;
                        case 4:
                            index0 = vertexCount + BitConverter.ToUInt32(mesh.IndexData, (j * 4) + 0) + 1;
                            index1 = vertexCount + BitConverter.ToUInt32(mesh.IndexData, (j * 4) + 4) + 1;
                            index2 = vertexCount + BitConverter.ToUInt32(mesh.IndexData, (j * 4) + 8) + 1;
                            break;
                        default:
                            index0 = 0;
                            index1 = 0;
                            index2 = 0;
                            break;
                    }

                    if (options.Normals && options.TextureCoordinates)
                    {
                        streamWriter.WriteLine("f " + index2 + "/" + index2 + "/" + index2 + " " + index1 + "/" + index1 + "/" + index1 + " " + index0 + "/" + index0 + "/" + index0);
                    }
                    else if (options.Normals)
                    {
                        streamWriter.WriteLine("f " + index2 + "//" + index2 + " " + index1 + "//" + index1 + " " + index0 + "//" + index0);
                    }
                    else if (options.TextureCoordinates)
                    {
                        streamWriter.WriteLine("f " + index2 + "/" + index2 + " " + index1 + "/" + index1 + " " + index0 + "/" + index0);
                    }
                    else
                    {
                        streamWriter.WriteLine("f " + index2 + " " + index1 + " " + index0);
                    }
                }

                vertexCount += (UInt32)mesh.VertexCount;
            }

            streamWriter.Close();
        }
Example #9
0
        protected void SetFromStream(Stream stream)
        {
            // try loading using standard .net first
            try
            {
                // We need to copy the stream over to a new, in-memory bitmap to
                // avoid keeping the input stream open.
                // See http://support.microsoft.com/kb/814675/en-us
                using(var img = Image.FromStream(stream))
                {
                    _image = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);

                    using (var gfx = Graphics.FromImage(_image))
                    {
                        gfx.DrawImage(img, 0, 0, img.Width, img.Height);
                    }

                    _result = LoadResult.Good;
                }         
            }
            catch (Exception)
            {
                // if this fails, load using DevIL
                using (var imp = new DevIL.ImageImporter())
                {
                    try
                    {
                        using(var devilImage = imp.LoadImageFromStream(stream))
                        {
                            devilImage.Bind();

                            var info = DevIL.Unmanaged.IL.GetImageInfo();
                            var bitmap = new Bitmap(info.Width, info.Height, PixelFormat.Format32bppArgb);
                            var rect = new Rectangle(0, 0, info.Width, info.Height);
                            var data = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

                            DevIL.Unmanaged.IL.CopyPixels(0, 0, 0, info.Width, info.Height, 1, DataFormat.BGRA, DataType.UnsignedByte, data.Scan0);

                            bitmap.UnlockBits(data);
                            _image = bitmap;
                            _result = LoadResult.Good;
                        }                
                    }
                    catch (Exception)
                    {
                        // TODO any other viable fall back image loaders?
                        _result = LoadResult.UnknownFileFormat;
                    }
                }
            }
        }
        public static Texture LoadFromFile(string filePath)
        {
            ImageImporter importer = new ImageImporter();
            ImageExporter exporter = new ImageExporter();
            Image image;
            image = importer.LoadImage(filePath);

            if (Path.GetExtension(filePath) != ".tga" && Path.GetExtension(filePath) != ".png")
            {
                if (!File.Exists(filePath.Replace(Path.GetExtension(filePath), ".tga")))
                    exporter.SaveImage(image, ImageType.Tga, filePath.Replace(Path.GetExtension(filePath), ".tga"));
                image = importer.LoadImage(filePath.Replace(Path.GetExtension(filePath), ".tga"));
            }

            //image.Bind();
            //var info = DevIL.Unmanaged.IL.GetImageInfo();
            //var bitmap = new System.Drawing.Bitmap(info.Width, info.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            //var rect = new System.Drawing.Rectangle(0, 0, info.Width, info.Height);
            //var data = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            //DevIL.Unmanaged.IL.CopyPixels(0, 0, 0, info.Width, info.Height, info.Depth, DataFormat.BGRA, DataType.UnsignedByte);
            //bitmap.UnlockBits(data);
            //var converter = new System.Drawing.ImageConverter();
            //var test = converter.ConvertTo(bitmap, typeof(byte[]));
            //var raw = (byte[])converter.ConvertTo(bitmap, typeof(byte[]));
            return new Texture(image);
        }
Example #11
0
        public bool LoadFiles(string path, bool ovveride = false)
        {
            if (!ovveride)
            {
                Clear();
            }
            try
            {
                currentImagePath = path;
                currentTextPath  = path.Replace(".dds", ".txt");
                if (File.Exists(currentImagePath) && File.Exists(currentTextPath))
                {
                    using (MemoryStream iconlist_ivtrm_img_ms = new MemoryStream(File.ReadAllBytes(currentImagePath)))
                    {
                        using (MemoryStream iconlist_ivtrm_txt_ms = new MemoryStream(File.ReadAllBytes(currentTextPath)))
                        {
                            using (DevIL.ImageImporter imImport = new DevIL.ImageImporter())
                            {
                                sourceBitmap = LoadImage(imImport, iconlist_ivtrm_img_ms);
                            }
                            if (sourceBitmap != null)
                            {
                                SortedList <String, Bitmap> results = new SortedList <String, Bitmap>();
                                List <Bitmap> zxczxc    = new List <Bitmap>();
                                List <String> fileNames = new List <string>();
                                w = 0;
                                h = 0;
                                int          counter = 0;
                                string       line;
                                Encoding     enc  = Encoding.GetEncoding("GBK");
                                StreamReader file = new StreamReader(iconlist_ivtrm_txt_ms, enc);
                                while ((line = file.ReadLine()) != null)
                                {
                                    switch (counter)
                                    {
                                    case 0:
                                        w = Int32.Parse(line);
                                        break;

                                    case 1:
                                        h = Int32.Parse(line);
                                        break;

                                    case 2:
                                        rows = Int32.Parse(line);
                                        break;

                                    case 3:
                                        cols = Int32.Parse(line);
                                        break;

                                    default:
                                        fileNames.Add(line);
                                        break;
                                    }
                                    counter++;
                                }

                                int x, y = 0;
                                for (int i = 0; i < fileNames.Count; i++)
                                {
                                    y = i / cols;
                                    x = i - y * cols;
                                    x = x * w;
                                    y = y * h;
                                    try
                                    {
                                        GeneralIcon icon = new GeneralIcon();
                                        icon.name     = fileNames[i];
                                        icon.Location = new Point(x, y);
                                        Bitmap pageBitmap = new Bitmap(w, h, PixelFormat.Format32bppArgb);
                                        using (Graphics graphics = Graphics.FromImage(pageBitmap))
                                        {
                                            graphics.DrawImage(sourceBitmap, new Rectangle(0, 0, w, h), new Rectangle(x, y, w, h), GraphicsUnit.Pixel);
                                        }
                                        icon.icon  = pageBitmap;
                                        icon.Index = i;
                                        currentIcons[icon.name] = icon;
                                    }
                                    catch (Exception) { }
                                }
                            }
                        }
                    }
                    //  currentIcons = currentIcons.OrderBy(u => u.Value.Index).ToDictionary(z => z.Key, y => y.Value);
                    return(true);
                }
            }
            catch { }

            return(false);
        }
Example #12
0
        public bool saveImage(string fileName)
        {
            try
            {
                string txtFile    = fileName.Replace(".dds", ".txt");
                string txtFilepng = fileName.Replace(".dds", ".png");
                try
                {
                    File.Delete(fileName);
                }

                catch { }
                GeneralIcon[] array = currentIcons.Values.ToArray();
                StringBuilder sb    = new StringBuilder();
                sb.AppendLine(w.ToString());
                sb.AppendLine(h.ToString());
                int rrow = array.Length / cols;
                sb.AppendLine(rrow.ToString());
                sb.AppendLine(cols.ToString());
                int imageWidth = w * cols;
                using (Bitmap img = new Bitmap(imageWidth, imageWidth, PixelFormat.Format32bppArgb))
                {
                    using (Graphics graphics = Graphics.FromImage(img))
                    {
                        int x, y = 0;

                        for (int i = 0; i < array.Length; i++)
                        {
                            GeneralIcon icon = array[i];
                            y = i / cols;
                            x = i - y * cols;
                            x = x * w;
                            y = y * h;
                            graphics.DrawImage(icon.icon, x, y);
                            sb.AppendLine(icon.name);
                        }
                    }
                    using (DevIL.ImageImporter ImImport = new DevIL.ImageImporter())
                    {
                        using (MemoryStream ms = new MemoryStream())
                        {
                            img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                            using (DevIL.Image IconImg = ImImport.LoadImageFromStream(new MemoryStream(ms.ToArray())))
                            {
                                IconImg.Bind();
                                ImageExporter exporter = new ImageExporter();
                                exporter.SaveImage(IconImg, ImageType.Dds, fileName);
                            }
                        }
                    }

                    File.WriteAllText(txtFile, sb.ToString(), Encoding.GetEncoding("GBK"));
                }
                Remake();
                return(true);
            }
            catch
            {
                return(false);
            }
        }
Example #13
0
        public void ExportModelToDirectoryWithExportOptions(Model model, string directory, ModelExportOptions exportOptions)
        {
            if (model == null || directory == null || exportOptions == null )
                return;

            NumberFormatInfo numberFormatInfo = new NumberFormatInfo();
            numberFormatInfo.NumberDecimalSeparator = ".";

            if (exportOptions.Package)
            {
                try
                {
                    DirectoryInfo directoryInfo = Directory.CreateDirectory(directory + @"\" + Path.GetFileNameWithoutExtension(model.Name));
                    directory = directoryInfo.FullName;
                }
                catch (Exception) { }
            }

            if (exportOptions.Textures)
            {
                ImageImporter imageImporter = new ImageImporter();
                ImageExporter imageExporter = new ImageExporter();

                foreach(string textureString in model.TextureStrings)
                {
                    MemoryStream textureMemoryStream = AssetManager.Instance.CreateAssetMemoryStreamByName(textureString);
                    if(textureMemoryStream == null)
                        continue;

                    Image textureImage = imageImporter.LoadImageFromStream(textureMemoryStream);
                    if(textureImage == null)
                        continue;

                    imageExporter.SaveImage(textureImage, exportOptions.TextureFormat.ImageType, directory + @"\" + Path.GetFileNameWithoutExtension(textureString) + @"." + exportOptions.TextureFormat.Extension);
                }
            }

            string path = string.Format(@"{0}\{1}.{2}", directory, Path.GetFileNameWithoutExtension(model.Name), Extension);

            FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write);
            StreamWriter streamWriter = new StreamWriter(fileStream);

            for (int i = 0; i < model.Meshes.Length; ++i)
            {
                Mesh mesh = model.Meshes[i];

                //positions
                List<Vector3> positions;
                if (mesh.GetPositions(out positions, 0))
                {
                    foreach (Vector3 position in positions)
                    {
                        Vector3 scaledPosition = Vector3.Multiply(position, exportOptions.Scale);
                        streamWriter.WriteLine("v {0} {1} {2}", scaledPosition.X.ToString(numberFormatInfo), scaledPosition.Y.ToString(numberFormatInfo), scaledPosition.Z.ToString(numberFormatInfo));
                    }
                }

                //texture coordinates
                if (exportOptions.TextureCoordinates)
                {
                    Vector2[] texCoords;
                    if (mesh.GetTexCoords(out texCoords, 0))
                    {
                        foreach (Vector2 texcoord in texCoords)
                            streamWriter.WriteLine("vt {0} {1}", texcoord.X.ToString(numberFormatInfo), (-texcoord.Y).ToString(numberFormatInfo));
                    }
                }

                //normals
                if (exportOptions.Normals)
                {
                    Vector3[] normals;
                    if (mesh.GetNormals(out normals, 0))
                    {
                        foreach (Vector3 normal in normals)
                            streamWriter.WriteLine("vn {0} {1} {2}", normal.X.ToString(numberFormatInfo), normal.Y.ToString(numberFormatInfo), normal.Z.ToString(numberFormatInfo));
                    }
                }
            }

            //faces
            uint vertexCount = 0;

            for (int i = 0; i < model.Meshes.Length; ++i)
            {
                Mesh mesh = model.Meshes[i];

                streamWriter.WriteLine("g Mesh{0}", i);

                uint[] indices;
                mesh.GetIndices(out indices);

                for (int j = 0; j < mesh.IndexCount; j += 3)
                {
                    uint index0 = indices[j + 0];
                    uint index1 = indices[j + 1];
                    uint index2 = indices[j + 2];

                    if (exportOptions.TextureCoordinates && exportOptions.Normals)
                    {
                        streamWriter.WriteLine("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}", index2, index1, index0);
                    }
                    else if (exportOptions.Normals)
                    {
                        streamWriter.WriteLine("f {0}//{0} {1}//{1} {2}//{2}", index2, index1, index0);
                    }
                    else if (exportOptions.TextureCoordinates)
                    {
                        streamWriter.WriteLine("f {0}/{0} {1}/{1} {2}/{2}", index2, index1, index0);
                    }
                    else
                    {
                        streamWriter.WriteLine("f {0} {1} {2}", index2, index1, index0);
                    }
                }

                vertexCount += (uint)mesh.VertexCount;
            }

            streamWriter.Close();
        }