Advertisement
Guest User

Untitled

a guest
Sep 7th, 2014
500
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.59 KB | None | 0 0
  1. using OpenTK;
  2. using OpenTK.Graphics;
  3. using OpenTK.Graphics.OpenGL;
  4. using OpenTK.Input;
  5. using System;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8. using System.IO;
  9. using System.Text.RegularExpressions;
  10. using GDIPixelFormat = System.Drawing.Imaging.PixelFormat;
  11. using GLPixelFormat = OpenTK.Graphics.OpenGL.PixelFormat;
  12.  
  13. namespace TFMV
  14. {
  15.     class Program
  16.     {
  17.         class Mesh
  18.         {
  19.             public int normalIndicesCount, normalIndicesOffset;
  20.             public int positionIndicesCount, positionIndicesOffset;
  21.             public int tangentIndicesCount, tangentIndicesOffset;
  22.             public int uvIndicesCount, uvIndicesOffset;
  23.  
  24.             public int normalCount, normalOffset;
  25.             public int positionCount, positionOffset;
  26.             public int tangentCount, tangentOffset;
  27.             public int uvCount, uvOffset;
  28.         }
  29.  
  30.         class MeshData
  31.         {
  32.             public int[] normalIndices;
  33.             public int[] positionIndices;
  34.             public int[] tangentIndices;
  35.             public int[] uvIndices;
  36.  
  37.             public Vector3[] normal;
  38.             public Vector3[] position;
  39.             public Vector4[] tangent;
  40.             public Vector2[] uv;
  41.         }
  42.  
  43.         static Mesh ReadMsh(string FileName)
  44.         {
  45.             string data = File.ReadAllText(FileName);
  46.             data = Regex.Replace(data, "[\\s\\n\\r\\t]+", " ");
  47.  
  48.             Mesh mesh = new Mesh();
  49.             string[] splitedData = data.Split(' ');
  50.  
  51.             string str = Regex.Match(data, "normal\\s=\\s{\\scount\\s=\\s\\d+,\\soffset\\s=\\s\\d+,\\s}", RegexOptions.IgnorePatternWhitespace).Value;
  52.             MatchCollection match = Regex.Matches(str, "\\d+");
  53.             mesh.normalIndicesCount = Convert.ToInt32(match[0].Value);
  54.             mesh.normalIndicesOffset = Convert.ToInt32(match[1].Value);
  55.  
  56.             str = Regex.Match(data, "position\\s=\\s{\\scount\\s=\\s\\d+,\\soffset\\s=\\s\\d+,\\s}", RegexOptions.IgnorePatternWhitespace).Value;
  57.             match = Regex.Matches(str, "\\d+");
  58.             mesh.positionIndicesCount = Convert.ToInt32(match[0].Value);
  59.             mesh.positionIndicesOffset = Convert.ToInt32(match[1].Value);
  60.  
  61.             str = Regex.Match(data, "tangent\\s=\\s{\\scount\\s=\\s\\d+,\\soffset\\s=\\s\\d+,\\s}", RegexOptions.IgnorePatternWhitespace).Value;
  62.             match = Regex.Matches(str, "\\d+");
  63.             mesh.tangentIndicesCount = Convert.ToInt32(match[0].Value);
  64.             mesh.tangentIndicesOffset = Convert.ToInt32(match[1].Value);
  65.  
  66.             str = Regex.Match(data, "uv0\\s=\\s{\\scount\\s=\\s\\d+,\\soffset\\s=\\s\\d+,\\s}", RegexOptions.IgnorePatternWhitespace).Value;
  67.             match = Regex.Matches(str, "\\d+");
  68.             mesh.uvIndicesCount = Convert.ToInt32(match[1].Value);
  69.             mesh.uvIndicesOffset = Convert.ToInt32(match[2].Value);
  70.  
  71.             str = Regex.Match(data, "normal\\s=\\s{\\scount\\s=\\s\\d+,\\snumComp\\s=\\s\\d+,\\soffset\\s=\\s\\d+,\\s}", RegexOptions.IgnorePatternWhitespace).Value;
  72.             match = Regex.Matches(str, "\\d+");
  73.             mesh.normalCount = Convert.ToInt32(match[0].Value);
  74.             mesh.normalOffset = Convert.ToInt32(match[2].Value);
  75.  
  76.             str = Regex.Match(data, "position\\s=\\s{\\scount\\s=\\s\\d+,\\snumComp\\s=\\s\\d+,\\soffset\\s=\\s\\d+,\\s}", RegexOptions.IgnorePatternWhitespace).Value;
  77.             match = Regex.Matches(str, "\\d+");
  78.             mesh.positionCount = Convert.ToInt32(match[0].Value);
  79.             mesh.positionOffset = Convert.ToInt32(match[2].Value);
  80.  
  81.             str = Regex.Match(data, "tangent\\s=\\s{\\scount\\s=\\s\\d+,\\snumComp\\s=\\s\\d+,\\soffset\\s=\\s\\d+,\\s}", RegexOptions.IgnorePatternWhitespace).Value;
  82.             match = Regex.Matches(str, "\\d+");
  83.             mesh.tangentCount = Convert.ToInt32(match[0].Value);
  84.             mesh.tangentOffset = Convert.ToInt32(match[2].Value);
  85.  
  86.             str = Regex.Match(data, "uv0\\s=\\s{\\scount\\s=\\s\\d+,\\snumComp\\s=\\s\\d+,\\soffset\\s=\\s\\d+,\\s}", RegexOptions.IgnorePatternWhitespace).Value;
  87.             match = Regex.Matches(str, "\\d+");
  88.             mesh.uvCount = Convert.ToInt32(match[1].Value);
  89.             mesh.uvOffset = Convert.ToInt32(match[3].Value);
  90.  
  91.             return mesh;
  92.         }
  93.  
  94.         static byte[] ReadBlob(string FileName)
  95.         {
  96.             return File.ReadAllBytes(FileName);
  97.         }
  98.  
  99.         static MeshData ParseBlob(byte[] data, Mesh mesh)
  100.         {
  101.             MeshData meshData = new MeshData();
  102.  
  103.             meshData.normalIndices = new int[mesh.normalIndicesCount / 4];
  104.             meshData.positionIndices = new int[mesh.positionIndicesCount / 4];
  105.             meshData.tangentIndices = new int[mesh.tangentIndicesCount / 4];
  106.             meshData.uvIndices = new int[mesh.uvIndicesCount / 4];
  107.  
  108.             for (int i = mesh.normalIndicesOffset, j = 0; j < mesh.normalIndicesCount / 4; i += 4, j++)
  109.                 meshData.normalIndices[j] = BitConverter.ToInt32(data, i);
  110.  
  111.             for (int i = mesh.positionIndicesOffset, j = 0; j < mesh.positionIndicesCount / 4; i += 4, j++)
  112.                 meshData.positionIndices[j] = BitConverter.ToInt32(data, i);
  113.  
  114.             for (int i = mesh.tangentIndicesOffset, j = 0; j < mesh.tangentIndicesCount / 4; i += 4, j++)
  115.                 meshData.tangentIndices[j] = BitConverter.ToInt32(data, i);
  116.  
  117.             for (int i = mesh.uvIndicesOffset, j = 0; j < mesh.uvIndicesCount / 4; i += 4, j++)
  118.                 meshData.uvIndices[j] = BitConverter.ToInt32(data, i);
  119.  
  120.             meshData.normal = new Vector3[mesh.normalCount / 3];
  121.             meshData.position = new Vector3[mesh.positionCount / 3];
  122.             meshData.tangent = new Vector4[mesh.tangentCount / 4];
  123.             meshData.uv = new Vector2[mesh.uvCount / 2];
  124.  
  125.             for (int i = mesh.normalOffset, j = 0; j < mesh.normalCount / 3 / 4; i += 12, j++)
  126.                 meshData.normal[j] = new Vector3(BitConverter.ToSingle(data, i), BitConverter.ToSingle(data, i + 4), BitConverter.ToSingle(data, i + 8));
  127.  
  128.             for (int i = mesh.positionOffset, j = 0; j < mesh.positionCount / 3 / 4; i += 12, j++)
  129.                 meshData.position[j] = new Vector3(BitConverter.ToSingle(data, i), BitConverter.ToSingle(data, i + 4), BitConverter.ToSingle(data, i + 8));
  130.  
  131.             for (int i = mesh.tangentOffset, j = 0; j < mesh.tangentCount / 4 / 4; i += 16, j++)
  132.                 meshData.tangent[j] = new Vector4(BitConverter.ToSingle(data, i), BitConverter.ToSingle(data, i + 4), BitConverter.ToSingle(data, i + 8), BitConverter.ToSingle(data, i + 12));
  133.  
  134.             for (int i = mesh.uvOffset, j = 0; j < mesh.uvCount / 2 / 4; i += 8, j++)
  135.                 meshData.uv[j] = new Vector2(BitConverter.ToSingle(data, i), BitConverter.ToSingle(data, i + 4));
  136.  
  137.             return meshData;
  138.         }
  139.  
  140.         static int TextureHandle = -1;
  141.  
  142.         static void Main(string[] Args)
  143.         {
  144.             Args = new[] { "E:\\Games\\Train Fever\\res\\models\\mesh\\vehicle\\train\\db_v100\\lod_1_v100.msh", "E:\\Games\\Train Fever\\res\\textures\\models\\vehicle\\train\\train_db_v100.tga" };
  145.  
  146.             if (Args.Length < 1)
  147.             {
  148.                 Console.WriteLine("Usage: TFMV.exe msh_model [tga_texture]");
  149.                 Console.ReadKey(true);
  150.                 return;
  151.             }
  152.  
  153.             string meshFileName = Args[0];
  154.             string blobFileName = Args[0] + ".blob";
  155.  
  156.             if (!File.Exists(meshFileName))
  157.             {
  158.                 Console.WriteLine("File {0} not found. Exiting", meshFileName);
  159.                 Console.ReadKey(true);
  160.                 return;
  161.             }
  162.  
  163.             if (!File.Exists(blobFileName))
  164.             {
  165.                 Console.WriteLine("File {0} not found. Exiting", blobFileName);
  166.                 Console.ReadKey(true);
  167.                 return;
  168.             }
  169.  
  170.             Mesh mesh = ReadMsh(meshFileName);
  171.             byte[] blob = ReadBlob(blobFileName);
  172.             MeshData meshData = ParseBlob(blob, mesh);
  173.  
  174.             GameWindow window = new GameWindow(800, 600, GraphicsMode.Default, "Train-Fever Model Viewer 0.2 by Omich", GameWindowFlags.Default, DisplayDevice.Default, 2, 0, GraphicsContextFlags.Default);
  175.  
  176.             window.Load += delegate(object sender, EventArgs e)
  177.             {
  178.                 GL.Enable(EnableCap.DepthTest);
  179.                 GL.Enable(EnableCap.Lighting);
  180.                 GL.Enable(EnableCap.Light0);
  181.                 GL.Enable(EnableCap.Texture2D);
  182.  
  183.                 GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
  184.  
  185.                 if (Args.Length > 1)
  186.                 {
  187.                     string textureFileName = Args[1];
  188.  
  189.                     if (!File.Exists(textureFileName))
  190.                         Console.WriteLine("File {0} not found. Skipping texture", blobFileName);
  191.                     else
  192.                     {
  193.                         TextureHandle = GL.GenTexture();
  194.                         GL.BindTexture(TextureTarget.Texture2D, TextureHandle);
  195.  
  196.                         Bitmap bitmap;
  197.  
  198.                         if (textureFileName.EndsWith(".tga"))
  199.                             bitmap = Paloma.TargaImage.LoadTargaImage(textureFileName);
  200.                         else
  201.                             bitmap = new Bitmap(textureFileName);
  202.  
  203.                         bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
  204.  
  205.                         BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
  206.  
  207.                         switch (bitmap.PixelFormat)
  208.                         {
  209.                             case GDIPixelFormat.Format24bppRgb:
  210.                                 GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, bitmap.Width, bitmap.Height, 0, GLPixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0);
  211.                                 break;
  212.  
  213.                             case GDIPixelFormat.Format32bppArgb:
  214.                                 GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bitmap.Width, bitmap.Height, 0, GLPixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
  215.                                 break;
  216.  
  217.                             default:
  218.                                 Console.WriteLine(bitmap.PixelFormat + " texture pixel format support not implemented. Skipping texture");
  219.                                 TextureHandle = -1;
  220.                                 break;
  221.                         }
  222.  
  223.                         if (TextureHandle != -1)
  224.                         {
  225.                             GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
  226.  
  227.                             GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
  228.                             GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
  229.  
  230.                             GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
  231.                             GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
  232.                         }
  233.  
  234.                         bitmap.UnlockBits(data);
  235.                         bitmap.Dispose();
  236.                     }
  237.                 }
  238.             };
  239.  
  240.             window.Resize += delegate(object sender, EventArgs e)
  241.             {
  242.                 GL.Viewport(0, 0, window.Width, window.Height);
  243.  
  244.                 GL.MatrixMode(MatrixMode.Projection);
  245.                 Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver2, (float)window.Width / window.Height, 0.1f, 1000.0f);
  246.                 GL.LoadMatrix(ref projection);
  247.  
  248.                 GL.MatrixMode(MatrixMode.Modelview);
  249.             };
  250.  
  251.             float hAngle = MathHelper.PiOver2;
  252.             float vAngle = MathHelper.PiOver2;
  253.  
  254.             bool mouseDown = false;
  255.  
  256.             int zoom = 15;
  257.  
  258.             float dragStartH = 0;
  259.             float dragStartV = 0;
  260.             int dragStartX = 0;
  261.             int dragStartY = 0;
  262.  
  263.             window.MouseDown += delegate(object sender, MouseButtonEventArgs e)
  264.             {
  265.                 if (e.Button == MouseButton.Left)
  266.                 {
  267.                     if (e.IsPressed)
  268.                     {
  269.                         mouseDown = true;
  270.                         dragStartH = hAngle;
  271.                         dragStartV = vAngle;
  272.                         dragStartX = e.X;
  273.                         dragStartY = e.Y;
  274.                     }
  275.                 }
  276.             };
  277.  
  278.             window.MouseUp += delegate(object sender, MouseButtonEventArgs e)
  279.             {
  280.                 if (e.Button == MouseButton.Left)
  281.                     mouseDown = false;
  282.             };
  283.  
  284.             window.MouseMove += delegate(object sender, MouseMoveEventArgs e)
  285.             {
  286.                 if (mouseDown)
  287.                 {
  288.                     int offsetX = e.X - dragStartX;
  289.                     int offsetY = e.Y - dragStartY;
  290.  
  291.                     hAngle = dragStartH - offsetX * 0.01f;
  292.                     vAngle = Math.Min(MathHelper.Pi - 0.01f, Math.Max(0.01f, dragStartV - offsetY * 0.01f));
  293.                 }
  294.             };
  295.  
  296.             window.MouseWheel += delegate(object sender, MouseWheelEventArgs e)
  297.             {
  298.                 zoom -= e.Delta;
  299.                 zoom = Math.Min(50, Math.Max(1, zoom));
  300.             };
  301.  
  302.             window.RenderFrame += delegate(object sender, FrameEventArgs e)
  303.             {
  304.                 GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
  305.  
  306.                 float x = (float)(zoom * Math.Sin(vAngle) * Math.Cos(hAngle));
  307.                 float y = (float)(zoom * Math.Sin(vAngle) * Math.Sin(hAngle));
  308.                 float z = (float)(zoom * Math.Cos(vAngle));
  309.  
  310.                 Matrix4 view = Matrix4.LookAt(new Vector3(x, y, z), Vector3.Zero, Vector3.UnitZ);
  311.                 GL.LoadMatrix(ref view);
  312.  
  313.                 if (TextureHandle != -1)
  314.                     GL.BindTexture(TextureTarget.Texture2D, TextureHandle);
  315.  
  316.                 GL.Begin(PrimitiveType.Triangles);
  317.  
  318.                 for (int i = 0; i < meshData.positionIndices.Length; i++)
  319.                 {
  320.                     GL.TexCoord2(meshData.uv[meshData.uvIndices[i]]);
  321.                     GL.Normal3(meshData.normal[meshData.normalIndices[i]]);
  322.                     GL.Vertex3(meshData.position[meshData.positionIndices[i]]);
  323.                 }
  324.  
  325.                 GL.End();
  326.  
  327.                 window.SwapBuffers();
  328.             };
  329.  
  330.             window.Run();
  331.         }
  332.     }
  333. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement