Esempio n. 1
0
        public void LoadModel(string filename)
        {
            ready = false;

            GL.ActiveTexture(TextureUnit.Texture0);

            this.filename = filename;

            if (filename.EndsWith(".m2"))
            {
                if (!cache.doodadBatches.ContainsKey(filename))
                {
                    M2Loader.LoadM2(filename, cache, m2ShaderProgram);
                }
                ActiveCamera.switchMode("perspective");
                ActiveCamera.Pos = new Vector3((cache.doodadBatches[filename].boundingBox.max.Z) + 11.0f, 0.0f, 4.0f);
                modelType = "m2";

                ready = true;
            }
            else if (filename.EndsWith(".wmo"))
            {
                if (!cache.worldModels.ContainsKey(filename))
                {
                    WMOLoader.LoadWMO(filename, cache, wmoShaderProgram);
                }
                ActiveCamera.switchMode("perspective");
                modelType = "wmo";

                ready = true;
            }
        }
Esempio n. 2
0
        public Render(string ModelPath, BackgroundWorker worker = null)
        {
            dragX = 0.0f;
            dragY = 0.0f;
            dragZ = 0.0f;

            if (worker == null)
            {
                this.worker = new BackgroundWorker();
            }
            else
            {
                this.worker = worker;
            }

            filename = ModelPath;

            System.Windows.Forms.Integration.WindowsFormsHost wfc = MainWindow.winFormControl;

            ActiveCamera     = new OldCamera((int)wfc.ActualWidth, (int)wfc.ActualHeight);
            ActiveCamera.Pos = new Vector3(-15.0f, 0.0f, 4.0f);

            if (filename.EndsWith(".m2"))
            {
                M2Loader.LoadM2(filename, cache);

                ActiveCamera.Pos = new Vector3(-15.0f, 0.0f, 4.0f);

                gLoaded = true;
            }
            else if (filename.EndsWith(".wmo"))
            {
                WMOLoader.LoadWMO(filename, cache);

                gLoaded = true;
                isWMO   = true;
            }

            glControl             = new GLControl(new OpenTK.Graphics.GraphicsMode(32, 24, 0, 8), 3, 0, OpenTK.Graphics.GraphicsContextFlags.Default);
            glControl.Width       = (int)wfc.ActualWidth;
            glControl.Height      = (int)wfc.ActualHeight;
            glControl.Left        = 0;
            glControl.Top         = 0;
            glControl.Load       += glControl_Load;
            glControl.Paint      += RenderFrame;
            glControl.MouseEnter += glControl_MouseEnter;
            glControl.MouseLeave += glControl_MouseLeave;
            glControl.Resize     += glControl_Resize;
            glControl.MakeCurrent();
            glControl.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;

            sw.Start();

            spentTime = 0.00;

            wfc.Child = glControl;
        }
Esempio n. 3
0
        private void RenderM2(string ModelPath)
        {
            using (var dg = new DisposeGroup())
            {
                string _BaseDir = ConfigurationManager.AppSettings["basedir"];

                //Load Shaders
                var pVSBlob        = dg.Add(ShaderBytecode.CompileFromFile("RenderWithCam.fx", "VS", "vs_4_0"));
                var inputSignature = dg.Add(ShaderSignature.GetInputSignature(pVSBlob));
                m_pVertexShader = new VertexShader(Device, pVSBlob);

                var pPSBlob = dg.Add(ShaderBytecode.CompileFromFile("RenderWithCam.fx", "PS", "ps_4_0"));
                m_pPixelShader = new PixelShader(Device, pPSBlob);

                //Define layout
                var layout = dg.Add(new InputLayout(Device, inputSignature, new[] {
                    new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
                    new InputElement("NORMAL", 0, Format.R32G32B32_Float, 16, 0),
                    new InputElement("TEXCOORD", 0, Format.R32G32_Float, 28, 0)
                }));

                M2Loader model = new M2Loader(_BaseDir, ModelPath, Device);
                model.LoadM2();
                WoWM2 m2 = model.m2;

                //Set count for use in draw later on
                indicecount = m2.indices.Count();

                if (m2.vertices.Count() == 0)
                {
                    modelLoaded = false;
                    return;
                }
                //Create buffers
                var vertexBuffer        = dg.Add(Buffer.Create(Device, BindFlags.VertexBuffer, m2.vertices));
                var vertexBufferBinding = new VertexBufferBinding(vertexBuffer, Utilities.SizeOf <Vector4>() + Utilities.SizeOf <Vector3>() + Utilities.SizeOf <Vector2>(), 0);
                var indexBuffer         = dg.Add(Buffer.Create(Device, BindFlags.IndexBuffer, m2.indices));

                Device.ImmediateContext.InputAssembler.InputLayout = (layout);
                Device.ImmediateContext.InputAssembler.SetVertexBuffers(0, vertexBufferBinding);
                Device.ImmediateContext.InputAssembler.SetIndexBuffer(indexBuffer, Format.R16_UInt, 0);
                Device.ImmediateContext.InputAssembler.PrimitiveTopology = (PrimitiveTopology.TriangleList);

                M2renderBatches = m2.renderBatches;
                m2materials     = m2.materials;

                Set(ref m_pConstantBuffer, new ConstantBuffer <Projections>(Device));
                Device.ImmediateContext.VertexShader.SetConstantBuffer(0, m_pConstantBuffer.Buffer);
            }

            //Make camera
            Camera = new WoWModelViewerCamera();
            Camera.SetProjParams((float)Math.PI / 2, 1, 0.01f, 50.0f);
            Camera.SetViewParams(new Vector3(10.0f, 10.0f, -10.0f), new Vector3(0.0f, 1.0f, 0.0f));
            Camera.Roll(-4f);
        }
Esempio n. 4
0
        public void LoadModel(string filename)
        {
            ready = false;
            GL.ActiveTexture(TextureUnit.Texture0);

            this.filename = filename;
            try
            {
                if (filename.EndsWith(".m2"))
                {
                    if (!cache.doodadBatches.ContainsKey(filename))
                    {
                        M2Loader.LoadM2(filename, cache, m2ShaderProgram);
                    }

                    if (!cache.doodadBatches.ContainsKey(filename))
                    {
                        return;
                    }

                    ActiveCamera.Pos = new Vector3((cache.doodadBatches[filename].boundingBox.max.Z) + 11.0f, 0.0f, 4.0f);
                    modelType        = "m2";

                    ready = true;
                }
                else if (filename.EndsWith(".wmo"))
                {
                    if (!cache.worldModels.ContainsKey(filename))
                    {
                        WMOLoader.LoadWMO(filename, cache, wmoShaderProgram);
                    }
                    modelType = "wmo";

                    ready = true;
                }
            }catch (Exception e)
            {
                Logger.WriteLine("Error occured when loading model " + filename + ": " + e.StackTrace);
            }

            ActiveCamera.ResetCamera();
        }
        public void LoadModel(string fileName)
        {
            GL.ActiveTexture(TextureUnit.Texture0);

            try
            {
                if (fileName.EndsWith(".m2"))
                {
                    var m2 = M2Loader.LoadM2(fileName, m2ShaderProgram);
                    activeObject     = new M2Container(m2, fileName);
                    ActiveCamera.Pos = new Vector3((m2.boundingBox.max.Z) + 11.0f, 0.0f, 4.0f);
                }
                else if (fileName.EndsWith(".wmo"))
                {
                    activeObject = new WMOContainer(WMOLoader.LoadWMO(fileName, wmoShaderProgram), fileName);
                }
            }
            catch (Exception e)
            {
                Logger.WriteLine("Error occured when loading model " + fileName + ": " + e.StackTrace);
            }

            ActiveCamera.ResetCamera();
        }
Esempio n. 6
0
        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);
                    }
                }
            }
        }
Esempio n. 7
0
        public Render(string ModelPath, BackgroundWorker worker = null)
        {
            dragX = 0.0f;
            dragY = 0.0f;
            dragZ = 0.0f;

            if (worker == null)
            {
                Console.WriteLine("Didn't get a backgroundworker, creating one!");
                this.worker = new BackgroundWorker();
            }
            else
            {
                this.worker = worker;
            }

            filename = ModelPath;

            System.Windows.Forms.Integration.WindowsFormsHost wfc = MainWindow.winFormControl;

            ActiveCamera     = new OldCamera((int)wfc.ActualWidth, (int)wfc.ActualHeight);
            ActiveCamera.Pos = new Vector3(-15.0f, 0.0f, 4.0f);

            if (filename.EndsWith(".m2"))
            {
                M2Loader.LoadM2(filename, cache);

                ActiveCamera.Pos = new Vector3(-15.0f, 0.0f, 4.0f);

                // The next few hackfixes can be removed once WMOs are done as well
                renderbatches = cache.doodadBatches[filename].submeshes;
                materials     = cache.doodadBatches[filename].mats;

                VBOid = new uint[2];

                VBOid[0] = (uint)cache.doodadBatches[filename].vertexBuffer;
                VBOid[1] = (uint)cache.doodadBatches[filename].indiceBuffer;

                gLoaded = true;
            }
            else if (filename.EndsWith(".wmo"))
            {
                WMOLoader.LoadWMO(filename, cache);

                //TODO

                //gLoaded = true;
                isWMO = true;
            }

            glControl             = new GLControl(new OpenTK.Graphics.GraphicsMode(32, 24, 0, 8), 3, 0, OpenTK.Graphics.GraphicsContextFlags.Default);
            glControl.Width       = (int)wfc.ActualWidth;
            glControl.Height      = (int)wfc.ActualHeight;
            glControl.Left        = 0;
            glControl.Top         = 0;
            glControl.Load       += glControl_Load;
            glControl.Paint      += RenderFrame;
            glControl.MouseEnter += glControl_MouseEnter;
            glControl.MouseLeave += glControl_MouseLeave;
            glControl.Resize     += glControl_Resize;
            glControl.MakeCurrent();
            glControl.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;

            sw.Start();

            spentTime = 0.00;

            wfc.Child = glControl;
        }
Esempio n. 8
0
        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);
                }
            }
        }