using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using OpenGL4NET; using System.Drawing; using System.Windows.Forms; namespace ZPG_2011_Moulis_Jan_A09B0359P { class LoadData { private static FileStream fStreamMTL; private static StreamReader srMTL; private static Vector3 diffuseColor; private static List tex; public static float[][] loadGroundHeight(String fileName, int groundSize) { Console.WriteLine("-=- Nacitani vyskove mapy \""+fileName+"\" -=-"); if (File.Exists(fileName)) { BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)); float[][] height = new float[groundSize][]; try { for (int z = 0; z < groundSize; z++) { height[z] = new float[128]; for (int x = 0; x < groundSize; x++) { height[z][x] = br.ReadByte() / 10f; } } } catch (EndOfStreamException) { Console.WriteLine("!!! Nastala chyba pri cteni mapy povrchu !!!\n!!! Program bude ukoncen !!!"); return null; } finally { br.Close(); } return height; } else { Console.WriteLine("!!! Nelze nalezt vyskovou mapu povrchu !!!\n!!! Program bude ukoncen !!!"); return null; } } public static Boolean loadTexture(uint[] textures, int position, String texturesName) { Console.WriteLine("-=- Nacitani textury \"" + texturesName + "\" -=-"); if (File.Exists(texturesName)) { Bitmap image = new Bitmap(texturesName); image.RotateFlip(RotateFlipType.RotateNoneFlipY); System.Drawing.Imaging.BitmapData bitmapdata; Rectangle rect = new Rectangle(0, 0, image.Width, image.Height); bitmapdata = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); gl.BindTexture(GL.TEXTURE_2D, textures[position]); gl.TexParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR); gl.TexParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR); gl.TexImage2D(GL.TEXTURE_2D, 0, (int)GL.RGB, image.Width, image.Height, 0, GL.BGR_EXT, GL.UNSIGNED_BYTE, bitmapdata.Scan0); gl.BindTexture(GL.TEXTURE_2D, 0); image.UnlockBits(bitmapdata); image.Dispose(); return true; } else { Console.WriteLine("!!! Nelze nalezt zadanou texturu !!!"); return false; } } public static OBJObject loadOBJFile(String fileName, float enlarge, uint[] textures) { Console.WriteLine("-=- Nacitani obj souboru \"" + fileName + "\" -=-"); if (!File.Exists(fileName)) { Console.WriteLine("!!! Nelze nalez zadany obj soubor "+fileName+ " !!!"); return null; } FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); StreamReader sr = new StreamReader(fStream, Encoding.UTF8, true); List objects = new List(); tex = new List(); List vertex = new List(); List normals = new List(); List textCoord = new List(); int countOfObjects = -1; int countOfVertex = 0; int countOfNormals = 0; int countOfTexCor = 0; int indexVertex = 0; int countOfVertexInObject = 0; int countOfFaces = 0; Random random = new Random(); while (sr.Peek() > -1) { String input = sr.ReadLine(); input = input.Replace(" ", " "); String numberInput = input.Replace('.', ','); String[] parameters = input.Split(' '); String[] numberParameters = numberInput.Split(' '); switch (parameters[0]) { case "o": //Console.WriteLine("novy objekt"); countOfObjects++; indexVertex = countOfVertex; countOfVertexInObject = 0; objects.Add(new SingleObject(enlarge)); vertex = new List(); tex.Add(0); break; case "v": countOfVertex++; Vector3 ver = new Vector3((float)System.Convert.ToDouble(numberParameters[1]), (float)System.Convert.ToDouble(numberParameters[2]), (float)System.Convert.ToDouble(numberParameters[3])); //Console.WriteLine("Vertex: "+countOfVertex+" " + ver); vertex.Add(ver); break; case "vn": countOfNormals++; Vector3 norm = new Vector3((float)System.Convert.ToDouble(numberParameters[1]), (float)System.Convert.ToDouble(numberParameters[2]), (float)System.Convert.ToDouble(numberParameters[3])); //Console.WriteLine("Normal: " + countOfNormals); normals.Add(norm); break; case "vt": countOfTexCor++; Vector3 text = new Vector3((float)System.Convert.ToDouble(numberParameters[1]), (float)System.Convert.ToDouble(numberParameters[2]), 0f); //Console.WriteLine("Texture: " + countOfTexCor); textCoord.Add(text); break; case "f": //Console.WriteLine("Pocet vertexu : " + countOfVertex+"\nPocet normal : "+countOfNormals+"\nPocet text : "+countOfTexCor); int[][] par = new int[numberParameters.Length - 1][]; // prevedeni parametru ze Stringu na Integer for (int i = 1; i < numberParameters.Length; i++) { String[] strPar = numberParameters[i].Split('/'); par[i - 1] = new int[3]; par[i - 1][0] = -1; par[i - 1][1] = -1; par[i - 1][2] = -1; for (int j = 0; j < strPar.Length; j++) { if (strPar[j] != "") { par[i - 1][j] = int.Parse(strPar[j]) - 1; } } } /*Console.WriteLine("Faces:"); for (int i = 0; i < par.Length; i++) { for (int j = 0; j < par[i].Length; j++) { Console.Write(par[i][j] + " "); } Console.WriteLine(); } Console.WriteLine("FaceEnd");*/ // f vrchol/textura/normala for (int i = 0; i < par.Length; i++) { if (par[i][0] != -1) { //Console.WriteLine("for"); float nx = 0; float ny = 0; float nz = 0; float texCoorX = 0; float texCoorY = 0; if (par[i][1] != -1) { //Console.WriteLine("textura"); texCoorX = textCoord[par[i][1]].x; texCoorY = textCoord[par[i][1]].y; } if (par[i][2] != -1) { //Console.WriteLine("normala"); nx = normals[par[i][2]].x; ny = normals[par[i][2]].y; nz = normals[par[i][2]].z; } //Console.WriteLine("addVertex " + (par[i][0] - indexVertex)); objects[countOfObjects].addVertex(vertex[(par[i][0] - indexVertex)].x, vertex[(par[i][0] - indexVertex)].y, vertex[(par[i][0] - indexVertex)].z, nx, ny, nz, diffuseColor.x, diffuseColor.y, diffuseColor.z, texCoorX, texCoorY); } } if (par.Length == 2) { objects[countOfObjects].addFace((uint)countOfVertexInObject, (uint)(countOfVertexInObject + 1), (uint)countOfVertexInObject); countOfVertexInObject += 2; } else { objects[countOfObjects].addFace((uint)countOfVertexInObject, (uint)(countOfVertexInObject + 1), (uint)(countOfVertexInObject + 2)); if (par.Length == 4) { objects[countOfObjects].addFace((uint)countOfVertexInObject, (uint)(countOfVertexInObject + 2), (uint)(countOfVertexInObject + 3)); countOfVertexInObject++; countOfFaces++; } countOfVertexInObject += 3; } countOfFaces++; break; case "usemtl": diffuseColor = new Vector3(random.Next(255) / 255.0f, random.Next(255) / 255.0f, random.Next(255) / 255.0f); if (parameters[1] != "(null)") { setMaterial(parameters[1], textures); } break; case "mtllib": openMTLFile(parameters[1]); break; } } sr.Close(); closeMTLFile(); for (int i = 0; i < objects.Count; i++) { objects[i].createBuffers(); } Console.WriteLine("-=- Info o \"" + fileName + "\" -=-"); Console.WriteLine(" - pocet objektu : " + (countOfObjects + 1)); Console.WriteLine(" - pocet vertexu : " + countOfVertex); Console.WriteLine(" - pocet normal : " + countOfNormals); Console.WriteLine(" - pocet texturovacich souradnic : " + countOfTexCor); Console.WriteLine(" - pocet ploch : " + countOfFaces); return new OBJObject(objects.ToArray(), tex.ToArray()); } private static void openMTLFile(String fileName){ fileName = "objekty/" + fileName; Console.WriteLine("-=- Otevreni mtl souboru \"" + fileName + "\" -=-"); if (!File.Exists(fileName)) { Console.WriteLine("!!! Nelze nalez zadany mtl soubor " + fileName + " !!!"); } else { fStreamMTL = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); srMTL = new StreamReader(fStreamMTL, Encoding.UTF8, true); } } private static void setMaterial(String material, uint[] textures) { if (srMTL != null) { fStreamMTL.Seek(0, SeekOrigin.Begin); srMTL = new StreamReader(fStreamMTL, Encoding.UTF8, true); bool myMaterial = false; bool end = false; while (srMTL.Peek() > -1) { String input = srMTL.ReadLine(); input = input.Replace(" ", " "); String numberInput = input.Replace('.', ','); String[] parameters = input.Split(' '); String[] numberParameters = numberInput.Split(' '); switch (parameters[0]) { case "newmtl": if (parameters[1] == material) { myMaterial = true; } else { if (myMaterial) { end = true; } } break; case "Kd": if (myMaterial) { diffuseColor = new Vector3((float)System.Convert.ToDouble(numberParameters[1]), (float)System.Convert.ToDouble(numberParameters[2]), (float)System.Convert.ToDouble(numberParameters[3])); } break; case "map_Kd": if (myMaterial) { parameters[1] = "textury/" + parameters[1]; uint[] textura = new uint[1]; gl.GenTextures(1, textura); if (loadTexture(textura, 0, parameters[1])) { tex[tex.Count - 1] = textura[0]; diffuseColor = new Vector3(1, 1, 1); } } break; } if (end) { break; } } } } private static void closeMTLFile() { if (srMTL != null) { srMTL.Close(); } } } }