private void LoadMap(string map, int centerx, int centery, int distance) { float TileSize = 1600.0f / 3.0f; //533.333 float ChunkSize = TileSize / 16.0f; //33.333 float UnitSize = ChunkSize / 8.0f; //4.166666 // ~~fun fact time with marlamin~~ this times 0.5 ends up being pixelspercoord on minimap float MapMidPoint = 32.0f / ChunkSize; GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.NormalArray); List <Vertex> verticelist = new List <Vertex>(); List <Int32> indicelist = new List <Int32>(); GL.Enable(EnableCap.Texture2D); worker.ReportProgress(0, "Loading ADT.."); for (int x = centerx; x < centerx + distance; x++) { for (int y = centery; y < centery + distance; y++) { string filename = "world\\maps\\" + map + "\\" + map + "_" + y + "_" + x + ".adt"; if (WoWFormatLib.Utils.CASC.FileExists(filename)) { ADTReader reader = new ADTReader(); reader.LoadADT(filename); Terrain adt = new Terrain(); adt.vertexBuffer = GL.GenBuffer(); adt.indiceBuffer = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer); GL.BindBuffer(BufferTarget.ElementArrayBuffer, adt.indiceBuffer); List <Material> materials = new List <Material>(); //Check if textures are already loaded or not, multiple ADTs close together probably use the same ones mostly //for (int ti = 0; ti < reader.adtfile.textures.filenames.Count(); ti++) //{ /* * Material material = new Material(); * material.filename = reader.adtfile.textures.filenames[ti]; * material.textureID = BLPLoader.LoadTexture(reader.adtfile.textures.filenames[ti], cache);*/ /* MAPTEXTURE TEXTURE HACKFIX STUFF STARTS HERE */ Material material = new Material(); material.filename = filename.Replace("maps", "maptextures").Replace(".adt", ".blp"); material.textureID = BLPLoader.LoadTexture(filename.Replace("maps", "maptextures").Replace(".adt", ".blp"), cache); /* MAPTEXTURE TEXTURE HACKFIX STUFF STOPS HERE */ materials.Add(material); //} var initialChunkY = reader.adtfile.chunks[0].header.position.Y; var initialChunkX = reader.adtfile.chunks[0].header.position.X; List <RenderBatch> renderBatches = new List <RenderBatch>(); for (uint c = 0; c < reader.adtfile.chunks.Count(); c++) { var chunk = reader.adtfile.chunks[c]; int off = verticelist.Count(); RenderBatch batch = new RenderBatch(); for (int i = 0, idx = 0; i < 17; i++) { for (int j = 0; j < (((i % 2) != 0) ? 8 : 9); j++) { //var v = new Vector3(chunk.header.position.Y - (j * UnitSize), chunk.vertices.vertices[idx++] + chunk.header.position.Z, -(chunk.header.position.X - (i * UnitSize * 0.5f))); Vertex v = new Vertex(); v.Normal = new Vector3(chunk.normals.normal_0[idx], chunk.normals.normal_1[idx], chunk.normals.normal_2[idx]); if (chunk.vertexShading.red != null && chunk.vertexShading.red[idx] != 127) { v.Color = new Vector3(chunk.vertexShading.blue[idx] / 255.0f, chunk.vertexShading.green[idx] / 255.0f, chunk.vertexShading.red[idx] / 255.0f); //v.Color = new Vector3(1.0f, 1.0f, 1.0f); } else { v.Color = new Vector3(1.0f, 1.0f, 1.0f); } // Commented out for maptexture hack //v.TexCoord = new Vector2(((float)j + (((i % 2) != 0) ? 0.5f : 0f)) / 8f, ((float)i * 0.5f) / 8f); v.Position = new Vector3(chunk.header.position.X - (i * UnitSize * 0.5f), chunk.header.position.Y - (j * UnitSize), chunk.vertices.vertices[idx++] + chunk.header.position.Z); if ((i % 2) != 0) { v.Position.Y -= 0.5f * UnitSize; } //Maptexture hackfix v.TexCoord = new Vector2(-(v.Position.Y - initialChunkX) / TileSize, -(v.Position.X - initialChunkY) / TileSize); verticelist.Add(v); } } batch.firstFace = (uint)indicelist.Count(); for (int j = 9; j < 145; j++) { indicelist.AddRange(new Int32[] { off + j + 8, off + j - 9, off + j }); indicelist.AddRange(new Int32[] { off + j - 9, off + j - 8, off + j }); indicelist.AddRange(new Int32[] { off + j - 8, off + j + 9, off + j }); indicelist.AddRange(new Int32[] { off + j + 9, off + j + 8, off + j }); if ((j + 1) % (9 + 8) == 0) { j += 9; } } batch.numFaces = (uint)(indicelist.Count()) - batch.firstFace; //if (!cache.materials.ContainsKey(reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[0].textureId].ToLower())) //{ // throw new Exception("MaterialCache does not have texture " + reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[0].textureId].ToLower()); //} //Commented out for maptexture hackfix /* * var layermats = new List<uint>(); * var alphalayermats = new List<int>(); * * for (int li = 0; li < reader.adtfile.texChunks[c].layers.Count(); li++) * { * if(reader.adtfile.texChunks[c].alphaLayer != null){ * alphalayermats.Add(BLPLoader.GenerateAlphaTexture(reader.adtfile.texChunks[c].alphaLayer[li].layer)); * } * layermats.Add((uint)cache.materials[reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[li].textureId].ToLower()]); * } * * batch.materialID = layermats.ToArray(); * batch.alphaMaterialID = alphalayermats.ToArray(); * */ var layermats = new List <uint>(); layermats.Add((uint)material.textureID); batch.materialID = layermats.ToArray(); renderBatches.Add(batch); } List <Doodad> doodads = new List <Doodad>(); for (int mi = 0; mi < reader.adtfile.objects.models.entries.Count(); mi++) { Console.WriteLine("Loading model #" + mi); var modelentry = reader.adtfile.objects.models.entries[mi]; var mmid = reader.adtfile.objects.m2NameOffsets.offsets[modelentry.mmidEntry]; var modelfilename = ""; for (int mmi = 0; mmi < reader.adtfile.objects.m2Names.offsets.Count(); mmi++) { if (reader.adtfile.objects.m2Names.offsets[mmi] == mmid) { modelfilename = reader.adtfile.objects.m2Names.filenames[mmi].ToLower(); } } var doodad = new Doodad(); doodad.filename = modelfilename; doodad.position = new Vector3(-(modelentry.position.X - 17066), modelentry.position.Y, -(modelentry.position.Z - 17066)); doodad.rotation = new Vector3(modelentry.rotation.X, modelentry.rotation.Y, modelentry.rotation.Z); doodad.scale = modelentry.scale; doodads.Add(doodad); if (cache.doodadBatches.ContainsKey(modelfilename)) { continue; } M2Loader.LoadM2(modelfilename, cache); } List <WorldModelBatch> worldModelBatches = new List <WorldModelBatch>(); // WMO loading goes here for (int wmi = 0; wmi < reader.adtfile.objects.worldModels.entries.Count(); wmi++) { Console.WriteLine("Loading WMO #" + wmi); string wmofilename = ""; var wmodelentry = reader.adtfile.objects.worldModels.entries[wmi]; var mwid = reader.adtfile.objects.wmoNameOffsets.offsets[wmodelentry.mwidEntry]; for (int wmfi = 0; wmfi < reader.adtfile.objects.wmoNames.offsets.Count(); wmfi++) { if (reader.adtfile.objects.wmoNames.offsets[wmfi] == mwid) { wmofilename = reader.adtfile.objects.wmoNames.filenames[wmfi].ToLower(); } } if (wmofilename.Length == 0) { throw new Exception("Unable to find filename for WMO!"); } WorldModelBatch wmobatch = new WorldModelBatch(); wmobatch.position = new Vector3(-(wmodelentry.position.X - 17066.666f), wmodelentry.position.Y, -(wmodelentry.position.Z - 17066.666f)); wmobatch.rotation = new Vector3(wmodelentry.rotation.X, wmodelentry.rotation.Y, wmodelentry.rotation.Z); wmobatch.worldModel = WMOLoader.LoadWMO(wmofilename, cache); worldModelBatches.Add(wmobatch); } adt.renderBatches = renderBatches.ToArray(); adt.doodads = doodads.ToArray(); adt.worldModelBatches = worldModelBatches.ToArray(); int[] indices = indicelist.ToArray(); Vertex[] vertices = verticelist.ToArray(); Console.WriteLine("Vertices in array: " + vertices.Count()); //37120, correct //indices = indicelist.ToArray(); Console.WriteLine("Indices in array: " + indices.Count()); //196608, should be 65.5k which is 196608 / 3. in triangles so its correct? GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Count() * 11 * sizeof(float)), vertices, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, adt.indiceBuffer); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(int)), indices, BufferUsageHint.StaticDraw); int verticeBufferSize = 0; int indiceBufferSize = 0; GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer); GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out verticeBufferSize); GL.BindBuffer(BufferTarget.ArrayBuffer, adt.indiceBuffer); GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out indiceBufferSize); Console.WriteLine("Vertices in buffer: " + verticeBufferSize / 11 / sizeof(float)); Console.WriteLine("Indices in buffer: " + indiceBufferSize / sizeof(int)); adts.Add(adt); } } } }
private void LoadM2(string modelpath) { if (!WoWFormatLib.Utils.CASC.FileExists(modelpath)) { throw new Exception("Model does not exist!"); } worker.ReportProgress(0, "Loading model.."); M2Reader reader = new M2Reader(); string filename = modelpath; reader.LoadM2(filename); VBOid = new uint[2]; GL.GenBuffers(2, VBOid); GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.NormalArray); worker.ReportProgress(20, "Reading model indices.."); List <uint> indicelist = new List <uint>(); for (int i = 0; i < reader.model.skins[0].triangles.Count(); i++) { indicelist.Add(reader.model.skins[0].triangles[i].pt1); indicelist.Add(reader.model.skins[0].triangles[i].pt2); indicelist.Add(reader.model.skins[0].triangles[i].pt3); } uint[] indices = indicelist.ToArray(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(uint)), indices, BufferUsageHint.StaticDraw); worker.ReportProgress(30, "Reading model vertices.."); Vertex[] vertices = new Vertex[reader.model.vertices.Count()]; for (int i = 0; i < reader.model.vertices.Count(); i++) { vertices[i].Position = new Vector3(reader.model.vertices[i].position.X, reader.model.vertices[i].position.Z, reader.model.vertices[i].position.Y * -1); vertices[i].Normal = new Vector3(reader.model.vertices[i].normal.X, reader.model.vertices[i].normal.Z, reader.model.vertices[i].normal.Y); vertices[i].TexCoord = new Vector2(reader.model.vertices[i].textureCoordX, reader.model.vertices[i].textureCoordY); } GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * 8 * sizeof(float)), vertices, BufferUsageHint.StaticDraw); GL.Enable(EnableCap.Texture2D); worker.ReportProgress(40, "Loading textures.."); materials = new Material[reader.model.textures.Count()]; for (int i = 0; i < reader.model.textures.Count(); i++) { Console.WriteLine("Loading texture " + i); string texturefilename = @"dungeons\textures\testing\color_13.blp"; materials[i].flags = reader.model.textures[i].flags; Console.WriteLine(" Requires type " + reader.model.textures[i].type + " texture"); switch (reader.model.textures[i].type) { case 0: Console.WriteLine(" Texture given in file!"); texturefilename = reader.model.textures[i].filename; break; case 1: string[] csfilenames = WoWFormatLib.DBC.DBCHelper.getTexturesByModelFilename(filename, (int)reader.model.textures[i].type, i); if (csfilenames.Count() > 0) { texturefilename = csfilenames[0]; } else { Console.WriteLine(" No type 1 texture found, falling back to placeholder texture"); } break; case 2: if (WoWFormatLib.Utils.CASC.FileExists(Path.ChangeExtension(modelpath, ".blp"))) { Console.WriteLine(" BLP exists!"); texturefilename = Path.ChangeExtension(modelpath, ".blp"); } else { Console.WriteLine(" Type 2 does not exist!"); //needs lookup? } break; case 11: string[] cdifilenames = WoWFormatLib.DBC.DBCHelper.getTexturesByModelFilename(filename, (int)reader.model.textures[i].type); for (int ti = 0; ti < cdifilenames.Count(); ti++) { if (WoWFormatLib.Utils.CASC.FileExists(modelpath.Replace(reader.model.name + ".M2", cdifilenames[ti] + ".blp"))) { texturefilename = modelpath.Replace(reader.model.name + ".M2", cdifilenames[ti] + ".blp"); } } break; default: Console.WriteLine(" Falling back to placeholder texture"); break; } Console.WriteLine(" Eventual filename is " + texturefilename); materials[i].textureID = BLPLoader.LoadTexture(texturefilename, cache); materials[i].filename = texturefilename; } worker.ReportProgress(60, "Loading renderbatches.."); renderbatches = new RenderBatch[reader.model.skins[0].submeshes.Count()]; for (int i = 0; i < reader.model.skins[0].submeshes.Count(); i++) { if (filename.StartsWith("character", StringComparison.CurrentCultureIgnoreCase)) { if (reader.model.skins[0].submeshes[i].submeshID != 0) { if (!reader.model.skins[0].submeshes[i].submeshID.ToString().EndsWith("01")) { continue; } } Console.WriteLine("Loading submesh " + reader.model.skins[0].submeshes[i].submeshID + "(" + reader.model.skins[0].submeshes[i].unk2 + ")"); } renderbatches[i].firstFace = reader.model.skins[0].submeshes[i].startTriangle; renderbatches[i].numFaces = reader.model.skins[0].submeshes[i].nTriangles; for (int tu = 0; tu < reader.model.skins[0].textureunit.Count(); tu++) { if (reader.model.skins[0].textureunit[tu].submeshIndex == i) { renderbatches[i].blendType = reader.model.renderflags[reader.model.skins[0].textureunit[tu].renderFlags].blendingMode; renderbatches[i].materialID = reader.model.texlookup[reader.model.skins[0].textureunit[tu].texture].textureID; } } } worker.ReportProgress(100, "Done."); gLoaded = true; }
private void LoadWMO(string modelpath) { Console.WriteLine("Loading WMO file.."); WMOReader reader = new WMOReader(); string filename = modelpath; //Load WMO reader.LoadWMO(filename); //Enable Vertex Arrays GL.EnableClientState(ArrayCap.VertexArray); //Enable Normal Arrays GL.EnableClientState(ArrayCap.NormalArray); //Enable TexCoord arrays GL.EnableClientState(ArrayCap.TextureCoordArray); //Set up buffer IDs VBOid = new uint[(reader.wmofile.group.Count() * 2) + 2]; GL.GenBuffers((reader.wmofile.group.Count() * 2) + 2, VBOid); for (int i = 0; i < reader.wmofile.doodadNames.Count(); i++) { //Console.WriteLine(reader.wmofile.doodadNames[i].filename); } for (int g = 0; g < reader.wmofile.group.Count(); g++) { if (reader.wmofile.group[g].mogp.vertices == null) { continue; } //Switch to Vertex buffer GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[g * 2]); Vertex[] vertices = new Vertex[reader.wmofile.group[g].mogp.vertices.Count()]; for (int i = 0; i < reader.wmofile.group[g].mogp.vertices.Count(); i++) { vertices[i].Position = new Vector3(reader.wmofile.group[g].mogp.vertices[i].vector.X, reader.wmofile.group[g].mogp.vertices[i].vector.Z, reader.wmofile.group[g].mogp.vertices[i].vector.Y); vertices[i].Normal = new Vector3(reader.wmofile.group[g].mogp.normals[i].normal.X, reader.wmofile.group[g].mogp.normals[i].normal.Z, reader.wmofile.group[g].mogp.normals[i].normal.Y); vertices[i].TexCoord = new Vector2(reader.wmofile.group[g].mogp.textureCoords[0][i].X, reader.wmofile.group[g].mogp.textureCoords[0][i].Y); } //Push to buffer GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * 8 * sizeof(float)), vertices, BufferUsageHint.StaticDraw); //Switch to Index buffer GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[(g * 2) + 1]); List <uint> indicelist = new List <uint>(); for (int i = 0; i < reader.wmofile.group[g].mogp.indices.Count(); i++) { indicelist.Add(reader.wmofile.group[g].mogp.indices[i].indice); } uint[] indices = indicelist.ToArray(); //Push to buffer GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(uint)), indices, BufferUsageHint.StaticDraw); } GL.Enable(EnableCap.Texture2D); materials = new Material[reader.wmofile.materials.Count()]; for (int i = 0; i < reader.wmofile.materials.Count(); i++) { for (int ti = 0; ti < reader.wmofile.textures.Count(); ti++) { if (reader.wmofile.textures[ti].startOffset == reader.wmofile.materials[i].texture1) { materials[i].textureID = BLPLoader.LoadTexture(reader.wmofile.textures[ti].filename, cache); materials[i].filename = reader.wmofile.textures[ti].filename; } } } int numRenderbatches = 0; //Get total amount of render batches for (int i = 0; i < reader.wmofile.group.Count(); i++) { if (reader.wmofile.group[i].mogp.renderBatches == null) { continue; } numRenderbatches = numRenderbatches + reader.wmofile.group[i].mogp.renderBatches.Count(); } renderbatches = new RenderBatch[numRenderbatches]; int rb = 0; for (int g = 0; g < reader.wmofile.group.Count(); g++) { var group = reader.wmofile.group[g]; if (group.mogp.renderBatches == null) { continue; } for (int i = 0; i < group.mogp.renderBatches.Count(); i++) { var batch = group.mogp.renderBatches[i]; renderbatches[rb].firstFace = batch.firstFace; renderbatches[rb].numFaces = batch.numFaces; if (batch.flags == 2) { renderbatches[rb].materialID = (uint)group.mogp.renderBatches[i].possibleBox2_3; } else { renderbatches[rb].materialID = group.mogp.renderBatches[i].materialID; } renderbatches[rb].blendType = reader.wmofile.materials[group.mogp.renderBatches[i].materialID].blendMode; renderbatches[rb].groupID = (uint)g; rb++; } } Console.WriteLine(" " + reader.wmofile.group.Count() + " skins"); Console.WriteLine(" " + materials.Count() + " materials"); Console.WriteLine(" " + renderbatches.Count() + " renderbatches"); Console.WriteLine(" " + reader.wmofile.group[0].mogp.vertices.Count() + " vertices"); Console.WriteLine("Done loading WMO file!"); gLoaded = true; isWMO = true; }
private void LoadMap(string map, int centerx, int centery, int distance) { float TileSize = 1600.0f / 3.0f; //533.333 float ChunkSize = TileSize / 16.0f; //33.333 float UnitSize = ChunkSize / 8.0f; //4.166666 // ~~fun fact time with marlamin~~ this times 0.5 ends up being pixelspercoord on minimap float MapMidPoint = 32.0f / ChunkSize; List <Vertex> verticelist = new List <Vertex>(); List <Int32> indicelist = new List <Int32>(); worker.ReportProgress(0, "Loading ADT.."); for (int x = centerx; x < centerx + distance; x++) { for (int y = centery; y < centery + distance; y++) { string filename = "world\\maps\\" + map + "\\" + map + "_" + x + "_" + y + ".adt"; if (!WoWFormatLib.Utils.CASC.FileExists(filename)) { continue; } ADTReader reader = new ADTReader(); reader.LoadADT(filename); Terrain adt = new Terrain(); List <Material> materials = new List <Material>(); for (int ti = 0; ti < reader.adtfile.textures.filenames.Count(); ti++) { Material material = new Material(); material.filename = reader.adtfile.textures.filenames[ti]; material.textureID = BLPLoader.LoadTexture(reader.adtfile.textures.filenames[ti], cache); materials.Add(material); } var initialChunkY = reader.adtfile.chunks[0].header.position.Y; var initialChunkX = reader.adtfile.chunks[0].header.position.X; List <RenderBatch> renderBatches = new List <RenderBatch>(); for (uint c = 0; c < reader.adtfile.chunks.Count(); c++) { var chunk = reader.adtfile.chunks[c]; int off = verticelist.Count(); RenderBatch batch = new RenderBatch(); for (int i = 0, idx = 0; i < 17; i++) { for (int j = 0; j < (((i % 2) != 0) ? 8 : 9); j++) { Vertex v = new Vertex(); v.Normal = new Vector3(chunk.normals.normal_0[idx], chunk.normals.normal_1[idx], chunk.normals.normal_2[idx]); if (chunk.vertexShading.red != null && chunk.vertexShading.red[idx] != 127) { v.Color = new Vector3(chunk.vertexShading.blue[idx] / 255.0f, chunk.vertexShading.green[idx] / 255.0f, chunk.vertexShading.red[idx] / 255.0f); } else { v.Color = new Vector3(1.0f, 1.0f, 1.0f); } v.TexCoord = new Vector2(j + ((i % 2) != 0 ? 0.5f : 0.0f), i * 0.5f); v.TexCoordAlpha = new Vector2(j / 8.0f + ((i % 2) != 0 ? (0.5f / 8.0f) : 0), i / 16.0f); v.Position = new Vector3(chunk.header.position.X - (i * UnitSize * 0.5f), chunk.header.position.Y - (j * UnitSize), chunk.vertices.vertices[idx++] + chunk.header.position.Z); if ((i % 2) != 0) { v.Position.Y -= 0.5f * UnitSize; } verticelist.Add(v); } } batch.firstFace = (uint)indicelist.Count(); for (int j = 9; j < 145; j++) { indicelist.AddRange(new Int32[] { off + j + 8, off + j - 9, off + j }); indicelist.AddRange(new Int32[] { off + j - 9, off + j - 8, off + j }); indicelist.AddRange(new Int32[] { off + j - 8, off + j + 9, off + j }); indicelist.AddRange(new Int32[] { off + j + 9, off + j + 8, off + j }); if ((j + 1) % (9 + 8) == 0) { j += 9; } } batch.numFaces = (uint)(indicelist.Count()) - batch.firstFace; if (reader.adtfile.texChunks[c].layers.Count() != 0) { if (!cache.materials.ContainsKey(reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[0].textureId].ToLower())) { throw new Exception("MaterialCache does not have texture " + reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[0].textureId].ToLower()); } var layermats = new List <uint>(); var alphalayermats = new List <int>(); for (int li = 0; li < reader.adtfile.texChunks[c].layers.Count(); li++) { if (reader.adtfile.texChunks[c].alphaLayer != null) { alphalayermats.Add(BLPLoader.GenerateAlphaTexture(reader.adtfile.texChunks[c].alphaLayer[li].layer)); } layermats.Add((uint)cache.materials[reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[li].textureId].ToLower()]); } batch.materialID = layermats.ToArray(); batch.alphaMaterialID = alphalayermats.ToArray(); } renderBatches.Add(batch); } List <Doodad> doodads = new List <Doodad>(); for (int mi = 0; mi < reader.adtfile.objects.models.entries.Count(); mi++) { Console.WriteLine("Loading model #" + mi); var modelentry = reader.adtfile.objects.models.entries[mi]; var mmid = reader.adtfile.objects.m2NameOffsets.offsets[modelentry.mmidEntry]; var modelfilename = ""; for (int mmi = 0; mmi < reader.adtfile.objects.m2Names.offsets.Count(); mmi++) { if (reader.adtfile.objects.m2Names.offsets[mmi] == mmid) { modelfilename = reader.adtfile.objects.m2Names.filenames[mmi].ToLower(); } } var doodad = new Doodad(); doodad.filename = modelfilename; doodad.position = new Vector3(-(modelentry.position.X - 17066), modelentry.position.Y, -(modelentry.position.Z - 17066)); doodad.rotation = new Vector3(modelentry.rotation.X, modelentry.rotation.Y, modelentry.rotation.Z); doodad.scale = modelentry.scale; doodads.Add(doodad); if (!cache.doodadBatches.ContainsKey(modelfilename)) { M2Loader.LoadM2(modelfilename, cache, modelShader); } } List <WorldModelBatch> worldModelBatches = new List <WorldModelBatch>(); for (int wmi = 0; wmi < reader.adtfile.objects.worldModels.entries.Count(); wmi++) { string wmofilename = ""; var wmodelentry = reader.adtfile.objects.worldModels.entries[wmi]; var mwid = reader.adtfile.objects.wmoNameOffsets.offsets[wmodelentry.mwidEntry]; for (int wmfi = 0; wmfi < reader.adtfile.objects.wmoNames.offsets.Count(); wmfi++) { if (reader.adtfile.objects.wmoNames.offsets[wmfi] == mwid) { wmofilename = reader.adtfile.objects.wmoNames.filenames[wmfi].ToLower(); } } if (wmofilename.Length == 0) { throw new Exception("Unable to find filename for WMO!"); } Console.WriteLine("Loading WMO #" + wmi + " (" + wmofilename + ")"); WorldModelBatch wmobatch = new WorldModelBatch(); wmobatch.position = new Vector3(-(wmodelentry.position.X - 17066.666f), wmodelentry.position.Y, -(wmodelentry.position.Z - 17066.666f)); wmobatch.rotation = new Vector3(wmodelentry.rotation.X, wmodelentry.rotation.Y, wmodelentry.rotation.Z); wmobatch.worldModel = WMOLoader.LoadWMO(wmofilename, cache, modelShader); worldModelBatches.Add(wmobatch); } GL.BindVertexArray(0); //GL.UseProgram(terrainShader); adt.renderBatches = renderBatches.ToArray(); adt.doodads = doodads.ToArray(); adt.worldModelBatches = worldModelBatches.ToArray(); adt.vao = GL.GenVertexArray(); Console.WriteLine("Generated ADT VAO " + adt.vao); GL.BindVertexArray(adt.vao); adt.vertexBuffer = GL.GenBuffer(); adt.indiceBuffer = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer); GL.BindBuffer(BufferTarget.ElementArrayBuffer, adt.indiceBuffer); adt.renderBatches = renderBatches.ToArray(); int[] indices = indicelist.ToArray(); Vertex[] vertices = verticelist.ToArray(); Console.WriteLine("Vertices in array: " + vertices.Count()); //37120, correct Console.WriteLine("Indices in array: " + indices.Count()); //196608, should be 65.5k which is 196608 / 3. in triangles so its correct? GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Count() * 13 * sizeof(float)), vertices, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, adt.indiceBuffer); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(int)), indices, BufferUsageHint.StaticDraw); int verticeBufferSize = 0; int indiceBufferSize = 0; GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer); GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out verticeBufferSize); GL.BindBuffer(BufferTarget.ArrayBuffer, adt.indiceBuffer); GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out indiceBufferSize); Console.WriteLine("Vertices in buffer: " + verticeBufferSize / 13 / sizeof(float)); Console.WriteLine("Indices in buffer: " + indiceBufferSize / sizeof(int)); GL.BindBuffer(BufferTarget.ArrayBuffer, adt.vertexBuffer); // var normalLoc = GL.GetAttribLocation(shaderProgram, "vNormal"); // GL.VertexAttribPointer(normalLoc, 3, VertexAttribPointerType.Float, false, 11 * sizeof(float), 0); var colorLoc = GL.GetAttribLocation(terrainShader, "vColor"); if (colorLoc != -1) { GL.VertexAttribPointer(colorLoc, 3, VertexAttribPointerType.Float, false, 13 * sizeof(float), 3 * sizeof(float)); } var texCoordLoc = GL.GetAttribLocation(terrainShader, "vTexCoord"); GL.EnableVertexAttribArray(texCoordLoc); GL.VertexAttribPointer(texCoordLoc, 2, VertexAttribPointerType.Float, false, 13 * sizeof(float), 6 * sizeof(float)); var texCoordAlphaLoc = GL.GetAttribLocation(terrainShader, "vTexCoordAlpha"); GL.EnableVertexAttribArray(texCoordAlphaLoc); GL.VertexAttribPointer(texCoordAlphaLoc, 2, VertexAttribPointerType.Float, false, 13 * sizeof(float), 8 * sizeof(float)); var posLoc = GL.GetAttribLocation(terrainShader, "vPosition"); GL.EnableVertexAttribArray(posLoc); GL.VertexAttribPointer(posLoc, 3, VertexAttribPointerType.Float, false, 13 * sizeof(float), 10 * sizeof(float)); GL.BindBuffer(BufferTarget.ElementArrayBuffer, adt.indiceBuffer); GL.BindVertexArray(0); adts.Add(adt); } } }