/// <summary> /// lataa skybox. /// </summary> /// <param name="skyName">skyboxin nimi, eli esim plainsky_ jos tiedostot on plainsky_front.jpg, plainsky_back.jpg jne</param> /// <param name="ext">tiedoston pääte, eli jpg, png, dds, ..</param> /// <param name="scale"></param> public void LoadSkybox(string skyName, string ext, float scale) { Texture.LoadTextures = false; // älä lataa objektin textureita automaattisesti sky = new ObjModel("skybox", "skybox.obj", scale, scale, scale); // lataa skybox Texture.LoadTextures = true; // seuraava saa ladatakin.. sky.Boundings = null; string[] side = { "bottom", "left", "back", "right", "top", "front" }; for (int q = 0; q < 6; q++) { sky.Meshes()[q].Boundings = null; string fileName = skyName + side[q] + "." + ext; Texture newSkyTex = new Texture(); TextureLoaders.TextureLoaderParameters.WrapModeS = TextureWrapMode.ClampToEdge; TextureLoaders.TextureLoaderParameters.WrapModeT = TextureWrapMode.ClampToEdge; newSkyTex = Texture.Load(fileName); // etsi sivun materiaali Material matInf = sky.GetMaterial(sky.Meshes()[q].MaterialName); if (matInf != null) { // korvaa vanhat texturet matInf.DiffuseTex = newSkyTex; } } TextureLoaders.TextureLoaderParameters.WrapModeS = TextureWrapMode.Repeat; TextureLoaders.TextureLoaderParameters.WrapModeT = TextureWrapMode.Repeat; }
/// <summary>Load resources here.</summary> protected override void OnLoad(EventArgs e) { base.OnLoad(e); GL.ClearColor(System.Drawing.Color.Blue); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Texture2D); GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); GL.Enable(EnableCap.CullFace); GL.ShadeModel(ShadingModel.Smooth); Light.Enable(); light.Position = new Vector3(80, 20, 0); light.UpdateColor(); light.SetLight(true); light.Rotation = new Vector3(0, 0, -40); toonBall = new ObjModel("ball", "ball.obj"); toonStar = new ObjModel("star", "star.obj"); world.Add(light); // lisää valo (aurinko) light.Add(toonBall.Clone()); // lisää valoon pallo, liikkuu valon mukana Random random = new Random(); for (int q = 0; q < OBJS; q++) { // nämä käyttää toon shaderia (kirjoitettu .mtl tiedostoon) if (q < OBJS / 2) objs[q] = toonBall.Clone(); else objs[q] = toonStar.Clone(); objs[q].Position.X = random.Next(20) - 10; objs[q].Position.Y = random.Next(20) - 10; objs[q].Position.Z = random.Next(20) - 10; // arvotaan, käytetäänkö lightingiä vai ei mitään if (random.Next(10) < 5) objs[q].LoadShader("lighting.vert", "lighting.frag"); else objs[q].LoadShader("", ""); // ei shaderia } for (int q = 0; q < OBJS; q++) toonBall.Add(objs[q]); world.Add(toonBall); cam.Position.Y = 1; cam.Position.Z = 2; Util.Set3DMode(); }
/// <summary> /// lataa kupu. /// </summary> /// <param name="skyName">texturen nimi</param> /// <param name="scale"></param> public void LoadSkydome(string skyName, float scale) { Texture.LoadTextures = false; // älä lataa objektin textureita automaattisesti sky = new ObjModel("skydome", "skydome.obj", scale, scale, scale); // lataa kupu Texture.LoadTextures = true; // seuraava saa ladatakin.. sky.Boundings = null; sky.Meshes()[0].Boundings = null; Texture newSkyTex = new Texture(); newSkyTex = Texture.Load(skyName); // etsi materiaali Material matInf = sky.GetMaterial(sky.Meshes()[0].MaterialName); if (matInf != null) { // korvaa vanha texture matInf.DiffuseTex = newSkyTex; } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); GL.ClearColor(0, 0, 0, 0); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Texture2D); GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); GL.Enable(EnableCap.CullFace); GL.ShadeModel(ShadingModel.Smooth); GL.Enable(EnableCap.Lighting); GL.Enable(EnableCap.Light0); Util.Set3DMode(); skydome.LoadSkydome("sky/space.jpg", 1f); world.Add(skydome); // skydome aina ekana koska se on kaikkien takana car = new ObjModel("car", "car.obj", 7, 7, 7); car.FixRotation.Y = -90; world.Add(car); const float Scale = 110; city = new ObjModel("city", "city.obj", Scale, Scale, Scale); world.Add(city); // lataa reitit carPath = new Path("carpath", "carpath.obj", Scale, Scale, Scale); // sama skaalaus ku cityssä carPath.FollowPath(car, true, true); cam.Position.Y = 60; cam.Front.Z = -10; cam.Update6DOF(); // car path on tehty xz tasossa (tai jotain y arvoja säädetty mutta menee aika pieleen), // joten korjataan ne y arvot. tämä katsoo joka vertexin kohdalta y arvon ja lisää siihen yp:n (tässä 0). carPath.FixPathY(0, ref city); }
/// <summary>Load resources here.</summary> protected override void OnLoad(EventArgs e) { base.OnLoad(e); GL.ClearColor(System.Drawing.Color.Blue); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Texture2D); GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); GL.Enable(EnableCap.CullFace); GL.ShadeModel(ShadingModel.Smooth); Light.Enable(); light.Position = new Vector3(10, 100, 10); light.UpdateColor(); light.SetLight(true); world.Add(light); // lisää valo skybox.LoadSkybox("sky/sky_", "jpg", 100); world.Add(skybox); carinfo.up = 0.2f; carinfo.down = 0.1f; carinfo.max = 5; car = new ObjModel("car", "car.obj", 2, 2, 2); car.FixRotation.Y = -90; car.Rotation.Y = 90; car2 = new ObjModel("truck", "truck.obj", 1, 1, 1); car2.Rotation.Y = 90; car2.Position.X = -10; car2.Position.Y = -0.2f; car2.Position.Z = -15; groundPlane.Load("2.jpg"); groundPlane.Position = new Vector3(0, -0.2f, 0); groundPlane.Rotation = new Vector3(90, 0, 0); world.Add(groundPlane); cam.Position.Z = 15; cam.Position.Y = 2; // lisätään autot maailmaan että coll.det. onnistuu world.Add(car); world.Add(car2); Util.Set3DMode(); Fog.CreateFog(FogMode.Exp, 20, 200, 0.02f); }
/// <summary> /// lataa mesh tiedosto /// </summary> /// <param name="fileName"></param> /// <param name="xs"></param> /// <param name="ys"></param> /// <param name="zs"></param> public void Load(string fileName, float xs, float ys, float zs) { pathData.Clear(); ObjModel mesh = null; List <Vector3> _vertex = new List <Vector3>(); List <Vector3> _normal = new List <Vector3>(); List <Vector2> _uv = new List <Vector2>(); string dir = Settings.DataDir; if (fileName.Contains("\\")) { int l = fileName.LastIndexOf("\\"); dir = dir + fileName.Substring(0, l + 1); } else if (fileName.Contains("/")) { int l = fileName.LastIndexOf("/"); dir = dir + fileName.Substring(0, l + 1); } fileName = Settings.DataDir + fileName; bool path = false; // jos reitti using (System.IO.StreamReader file = new System.IO.StreamReader(fileName)) { // tiedosto muistiin string data = file.ReadToEnd(); data = data.Replace('\r', ' '); // pilko se string[] lines = data.Split('\n'); int numOfFaces = 0; for (int q = 0; q < lines.Length; q++) { string[] ln = lines[q].Split(' '); // pilko datat if (ln[0] == "f") { numOfFaces++; } } // lue kaikki datat objektiin ja indexit mesheihin for (int q = 0; q < lines.Length; q++) { string line = lines[q]; if (line.StartsWith("#")) { continue; } string[] ln = line.Split(' '); // pilko datat if (ln[0] == "v") // vertex x y z { float x = (Util.GetFloat(ln[1]) - mesh.Position.X) * xs; float y = (Util.GetFloat(ln[2]) - mesh.Position.Y) * ys; float z = (Util.GetFloat(ln[3]) - mesh.Position.Z) * zs; if (path) { pathData.Add(new Vector3(x, y, z)); } else { _vertex.Add(new Vector3(x, y, z)); } continue; } if (ln[0] == "vn") // normal x y z { _normal.Add(new Vector3(Util.GetFloat(ln[1]), Util.GetFloat(ln[2]), Util.GetFloat(ln[3]))); continue; } if (ln[0] == "vt") // texcoord U V { _uv.Add(new Vector2(Util.GetFloat(ln[1]), Util.GetFloat(ln[2]))); continue; } // uusi objekti if (ln[0] == "o" || ln[0] == "g") { if (mesh != null) { meshes.Add(mesh); // talteen } mesh = new ObjModel(ln[1]); mesh.material = material; // Nimessä voi olla ohjeita mitä muuta halutaan, esim: // * Path_reitti1 jolloin ei ladata objektia mutta reitti jota pitkin kamera/objektit voi kulkea. // * BBox_nimi/BSphere_nimi jolloin tämä onkin nimi-objektin bounding box/sphere. if (mesh.Name.Contains("Path_")) { path = true; } else if (mesh.Name.Contains("BBox_") || mesh.Name.Contains("BSphere_")) { // TODO: bbox_ bsphere_ } continue; } // materiaali if (ln[0] == "usemtl") { // jos kesken meshin materiaali vaihtuu, luodaan uusi obu johon loput facet if (lines[q - 1].StartsWith("f")) { meshes.Add(mesh); Vector3 tmpPos = mesh.Position; mesh = new ObjModel(mesh.Name); mesh.material = material; mesh.Position = tmpPos; // samaa objektia, niin sama Position } mesh.MaterialName = ln[1]; continue; } if (ln[0] == "f") { // ota talteen f rivi: // f vertex/uv/normal vertex/uv/normal vertex/uv/normal // eli esim: f 4/4/2 5/5/3 7/2/4 // tarkistetaan jos ilman texcoordei eli f 4/4 5/4 6/4 tai f 2//3 jne tai ilman / merkkejä. int dv = 0; for (int t = 0; t < line.Length; t++) { if (line[t] == '/') { dv++; } } if (line.Contains("//")) { dv = 0; // ei ole texindexei } line = line.Replace("//", " "); line = line.Replace("/", " "); string[] _ln = line.Split(' '); if (dv == 0 || dv == 3) // luultavasti nyt ei ole texturecoordinaatteja { mesh._vertexInd.Add(Int32.Parse(_ln[1]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[3]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[5]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[2]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[4]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[6]) - 1); } else // kaikki mukana { mesh._vertexInd.Add(Int32.Parse(_ln[1]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[4]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[7]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[2]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[5]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[8]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[3]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[6]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[9]) - 1); } continue; } // materiaalitiedosto if (ln[0] == "mtllib") { try { // ladataan objektille materiaalitiedot (mesheille otetaan talteen materialname joka viittaa sitten näihin materiaaleihin) material = new Material(); material.Load(dir + ln[1], Texture.LoadTextures); } catch (Exception e) { Log.WriteDebugLine(e.ToString()); } } } if (mesh != null) { meshes.Add(mesh); } // pathille ei luoda objektia, se on vain kasa vertexejä if (path == false) { int cc = 0; vertices = new Vertex[numOfFaces * 3]; for (int m = 0; m < meshes.Count; m++) { meshes[m].vertices = new Vertex[meshes[m]._vertexInd.Count]; for (int q = 0; q < meshes[m]._vertexInd.Count; q++) { // mesh datat meshes[m].vertices[q].vertex = _vertex[meshes[m]._vertexInd[q]]; meshes[m].vertices[q].normal = _normal[meshes[m]._normalInd[q]]; if (meshes[m]._uvInd.Count != 0) { meshes[m].vertices[q].uv_or_color = new Vector4(_uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y, _uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y); } // pistetään myös objektille kaikki vertexit yhteen klimppiin. //TODO Miks? vie vaa muistia nii paljo, mesheissä kumminki nuo datat säilytetään. // jos tää on VAIN collisionia varten, siihe ny o helppo tehdä se et se menee objektin puun läpi // ni sit ei tartte tätä vertices[cc].vertex = _vertex[meshes[m]._vertexInd[q]]; vertices[cc].normal = _normal[meshes[m]._normalInd[q]]; if (meshes[m]._uvInd.Count != 0) { vertices[cc].uv_or_color = new Vector4(_uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y, _uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y); } cc++; } // index taulukko meshes[m].indices = new int[meshes[m]._vertexInd.Count]; for (int q = 0; q < meshes[m]._vertexInd.Count; q++) { meshes[m].indices[q] = q; } meshes[m].vbo = new VBO(); meshes[m].vbo.DataToVBO(meshes[m].vertices, meshes[m].indices); // meshin bounding volume meshes[m].Boundings = new BoundingVolume(); meshes[m].Boundings.CreateBoundingVolume(meshes[m]); // lataa glsl koodit string shader = material.GetMaterial(meshes[m].MaterialName).ShaderName; if (shader != "") { mesh.Shader = new GLSL(); mesh.Shader.Load(shader + ".vert", shader + ".frag"); } if (material.GetMaterial(meshes[m].MaterialName).Dissolve < 1.0f) { IsTranslucent = true; } } // koko objektin bounding volume IsRendObj = false; // childeissä rendattavat objektit, tässä ei ole rendattavaa, vain paikka Boundings = new BoundingVolume(); Boundings.CreateBoundingVolume(this); // lisätään objektille meshit childeiks for (int q = 0; q < meshes.Count; q++) { Add(meshes[q]); } Log.WriteDebugLine("Object: " + Name + " meshes: " + meshes.Count); } _vertex.Clear(); _normal.Clear(); _uv.Clear(); for (int q = 0; q < meshes.Count; q++) { meshes[q]._vertexInd.Clear(); meshes[q]._normalInd.Clear(); meshes[q]._uvInd.Clear(); } } }
/// <summary>Load resources here.</summary> protected override void OnLoad(EventArgs e) { base.OnLoad(e); GL.ClearColor(System.Drawing.Color.Blue); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Texture2D); GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); GL.Enable(EnableCap.CullFace); GL.ShadeModel(ShadingModel.Smooth); GL.Enable(EnableCap.ColorMaterial); Light.Enable(); light.Position = new Vector3(50, 80, -100); light.SetLight(true); world.Add(light); // lisää valo (aurinko) // Lataukset skybox.LoadSkybox("sky/sky2_", "jpg", 100); world.Add(skybox); // skybox aina ekana koska se on kaikkien takana obj[0] = new ObjModel("head", "Head/head.obj"); // ladataan kerran obj[0].Position.Z = 0; // tehdään muutama kopio, siirretään vierekkäin obj[1] = obj[0].Clone(); obj[1].Position.X = 5; obj[2] = obj[0].Clone(); obj[2].Position.X = 10; obj[3] = obj[0].Clone(); obj[3].Position.X = 15; obj[4] = obj[0].Clone(); obj[4].Position.X = 20; obj[5] = new ObjModel("arm", "Head/arm.obj"); obj[1].Add(obj[5]); // pää nro 2:seen lisätään käsi // lasketaan groupille bounding volume obj[1].Boundings.CreateBoundingVolume(obj[1]); // lisää kamat worldiin for (int q = 0; q < 4; q++) world.Add(obj[q]); // rumilus uglyModel = new AnimatedModel("ukko", "Ugly/Ukko.mesh"); uglyModel.LoadAnim("act", "Ugly/Ukko_action2.anim"); uglyModel.UseAnimation("act"); uglyModel.Position.X = -4; uglyModel.FixRotation.X = -90; // ukko on "makaavassa" asennossa joten nostetaan se fixRotationilla pystyyn. world.Add(uglyModel); Mesh scene = new ObjModel("scene", "scene1.obj", 20, 20, 20); scene.Position.X = 10; // katos (sen nimi on toi None_Material__9) pitää pistää 2 puoliseks, muuten se ei näy alhaalta päin scene.SetDoubleSided("None_Material__9", true); // samoin seinät 2 puolisiks (blenderistä ja tutkimalla .obj tiedostoa selviää nämä nimet) scene.SetDoubleSided("None_Material__12", true); world.Add(scene); // lisää scene cam.Position.Y = 5; cam.Position.Z = 15; Util.Set3DMode(); }
/// <summary> /// lataa mesh tiedosto /// </summary> /// <param name="fileName"></param> /// <param name="xs"></param> /// <param name="ys"></param> /// <param name="zs"></param> public void Load(string fileName, float xs, float ys, float zs) { pathData.Clear(); ObjModel mesh = null; List<Vector3> _vertex = new List<Vector3>(); List<Vector3> _normal = new List<Vector3>(); List<Vector2> _uv = new List<Vector2>(); string dir = Settings.DataDir; if (fileName.Contains("\\")) { int l = fileName.LastIndexOf("\\"); dir = dir + fileName.Substring(0, l + 1); } else if (fileName.Contains("/")) { int l = fileName.LastIndexOf("/"); dir = dir + fileName.Substring(0, l + 1); } fileName = Settings.DataDir + fileName; bool path = false; // jos reitti using (System.IO.StreamReader file = new System.IO.StreamReader(fileName)) { // tiedosto muistiin string data = file.ReadToEnd(); data = data.Replace('\r', ' '); // pilko se string[] lines = data.Split('\n'); int numOfFaces = 0; for (int q = 0; q < lines.Length; q++) { string[] ln = lines[q].Split(' '); // pilko datat if (ln[0] == "f") numOfFaces++; } // lue kaikki datat objektiin ja indexit mesheihin for (int q = 0; q < lines.Length; q++) { string line = lines[q]; if (line.StartsWith("#")) continue; string[] ln = line.Split(' '); // pilko datat if (ln[0] == "v") // vertex x y z { float x = (Util.GetFloat(ln[1]) - mesh.Position.X) * xs; float y = (Util.GetFloat(ln[2]) - mesh.Position.Y) * ys; float z = (Util.GetFloat(ln[3]) - mesh.Position.Z) * zs; if (path) pathData.Add(new Vector3(x, y, z)); else _vertex.Add(new Vector3(x, y, z)); continue; } if (ln[0] == "vn") // normal x y z { _normal.Add(new Vector3(Util.GetFloat(ln[1]), Util.GetFloat(ln[2]), Util.GetFloat(ln[3]))); continue; } if (ln[0] == "vt") // texcoord U V { _uv.Add(new Vector2(Util.GetFloat(ln[1]), Util.GetFloat(ln[2]))); continue; } // uusi objekti if (ln[0] == "o" || ln[0] == "g") { if (mesh != null) meshes.Add(mesh); // talteen mesh = new ObjModel(ln[1]); mesh.material = material; // Nimessä voi olla ohjeita mitä muuta halutaan, esim: // * Path_reitti1 jolloin ei ladata objektia mutta reitti jota pitkin kamera/objektit voi kulkea. // * BBox_nimi/BSphere_nimi jolloin tämä onkin nimi-objektin bounding box/sphere. if (mesh.Name.Contains("Path_")) { path = true; } else if (mesh.Name.Contains("BBox_") || mesh.Name.Contains("BSphere_")) { // TODO: bbox_ bsphere_ } continue; } // materiaali if (ln[0] == "usemtl") { // jos kesken meshin materiaali vaihtuu, luodaan uusi obu johon loput facet if (lines[q - 1].StartsWith("f")) { meshes.Add(mesh); Vector3 tmpPos = mesh.Position; mesh = new ObjModel(mesh.Name); mesh.material = material; mesh.Position = tmpPos; // samaa objektia, niin sama Position } mesh.MaterialName = ln[1]; continue; } if (ln[0] == "f") { // ota talteen f rivi: // f vertex/uv/normal vertex/uv/normal vertex/uv/normal // eli esim: f 4/4/2 5/5/3 7/2/4 // tarkistetaan jos ilman texcoordei eli f 4/4 5/4 6/4 tai f 2//3 jne tai ilman / merkkejä. int dv = 0; for (int t = 0; t < line.Length; t++) if (line[t] == '/') dv++; if (line.Contains("//")) dv = 0; // ei ole texindexei line = line.Replace("//", " "); line = line.Replace("/", " "); string[] _ln = line.Split(' '); if (dv == 0 || dv == 3) // luultavasti nyt ei ole texturecoordinaatteja { mesh._vertexInd.Add(Int32.Parse(_ln[1]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[3]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[5]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[2]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[4]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[6]) - 1); } else // kaikki mukana { mesh._vertexInd.Add(Int32.Parse(_ln[1]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[4]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[7]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[2]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[5]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[8]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[3]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[6]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[9]) - 1); } continue; } // materiaalitiedosto if (ln[0] == "mtllib") { try { // ladataan objektille materiaalitiedot (mesheille otetaan talteen materialname joka viittaa sitten näihin materiaaleihin) material = new Material(); material.Load(dir + ln[1], Texture.LoadTextures); } catch (Exception e) { Log.WriteDebugLine(e.ToString()); } } } if (mesh != null) meshes.Add(mesh); // pathille ei luoda objektia, se on vain kasa vertexejä if (path == false) { int cc = 0; vertices = new Vertex[numOfFaces * 3]; for (int m = 0; m < meshes.Count; m++) { meshes[m].vertices = new Vertex[meshes[m]._vertexInd.Count]; for (int q = 0; q < meshes[m]._vertexInd.Count; q++) { // mesh datat meshes[m].vertices[q].vertex = _vertex[meshes[m]._vertexInd[q]]; meshes[m].vertices[q].normal = _normal[meshes[m]._normalInd[q]]; if (meshes[m]._uvInd.Count != 0) meshes[m].vertices[q].uv_or_color = new Vector4(_uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y, _uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y); // pistetään myös objektille kaikki vertexit yhteen klimppiin. //TODO Miks? vie vaa muistia nii paljo, mesheissä kumminki nuo datat säilytetään. // jos tää on VAIN collisionia varten, siihe ny o helppo tehdä se et se menee objektin puun läpi // ni sit ei tartte tätä vertices[cc].vertex = _vertex[meshes[m]._vertexInd[q]]; vertices[cc].normal = _normal[meshes[m]._normalInd[q]]; if (meshes[m]._uvInd.Count != 0) vertices[cc].uv_or_color = new Vector4(_uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y, _uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y); cc++; } // index taulukko meshes[m].indices = new int[meshes[m]._vertexInd.Count]; for (int q = 0; q < meshes[m]._vertexInd.Count; q++) meshes[m].indices[q] = q; meshes[m].vbo = new VBO(); meshes[m].vbo.DataToVBO(meshes[m].vertices, meshes[m].indices); // meshin bounding volume meshes[m].Boundings = new BoundingVolume(); meshes[m].Boundings.CreateBoundingVolume(meshes[m]); // lataa glsl koodit string shader = material.GetMaterial(meshes[m].MaterialName).ShaderName; if (shader != "") { mesh.Shader = new GLSL(); mesh.Shader.Load(shader + ".vert", shader + ".frag"); } if (material.GetMaterial(meshes[m].MaterialName).Dissolve < 1.0f) IsTranslucent = true; } // koko objektin bounding volume IsRendObj = false; // childeissä rendattavat objektit, tässä ei ole rendattavaa, vain paikka Boundings = new BoundingVolume(); Boundings.CreateBoundingVolume(this); // lisätään objektille meshit childeiks for (int q = 0; q < meshes.Count; q++) { Add(meshes[q]); } Log.WriteDebugLine("Object: " + Name + " meshes: " + meshes.Count); } _vertex.Clear(); _normal.Clear(); _uv.Clear(); for (int q = 0; q < meshes.Count; q++) { meshes[q]._vertexInd.Clear(); meshes[q]._normalInd.Clear(); meshes[q]._uvInd.Clear(); } } }