예제 #1
0
        public static int LoadTexture(string filename, CacheStorage cache)
        {
            GL.ActiveTexture(TextureUnit.Texture0);

            filename = filename.ToLower();
            
            if (cache.materials.ContainsKey(filename))
            {
               // Console.WriteLine("[CACHE HIT] " + filename);
                return cache.materials[filename];
            }

            //Console.WriteLine("[CACHE MISS] " + filename);

            int textureId = GL.GenTexture();

            var blp = new BLPReader();

            blp.LoadBLP(filename);

            if (blp.bmp == null)
            {
                throw new Exception("BMP is null!");
            }
            else
            {
                GL.BindTexture(TextureTarget.Texture2D, textureId);
                cache.materials.Add(filename, textureId);
                System.Drawing.Imaging.BitmapData bmp_data = blp.bmp.LockBits(new System.Drawing.Rectangle(0, 0, blp.bmp.Width, blp.bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
                blp.bmp.UnlockBits(bmp_data);
            }

            // Console.WriteLine("[CACHE ADD] " + filename);

            return textureId;
        }
예제 #2
0
        private void LoadTile(string basedir, int[] tile)
        {
            var x = tile[0];
            var y = tile[1];
            string _SelectedMapName = ((KeyValuePair<int, string>)MapListBox.SelectedValue).Value;
            Rectangle rect = new Rectangle();
            rect.Name = _SelectedMapName.Replace("'", string.Empty).Replace(" ", string.Empty) + x.ToString("D2") + "_" + y.ToString("D2"); //leading zeros just like adts, this breaks when the mapname has special characters (zg)D:
            rect.Width = WDTGrid.Width / 64;
            rect.Height = WDTGrid.Height / 64;
            rect.VerticalAlignment = VerticalAlignment.Top;
            rect.HorizontalAlignment = HorizontalAlignment.Left;

            if (File.Exists(basedir + "World\\Minimaps\\" + _SelectedMapName + "\\map" + x.ToString("D2") + "_" + y.ToString("D2") + ".blp"))
            {
                rect.MouseLeftButtonDown += new MouseButtonEventHandler(Rectangle_Mousedown);
                var xmargin = x * rect.Width;
                var ymargin = y * rect.Height;
                rect.Margin = new Thickness(xmargin, ymargin, 0, 0);
                var blp = new BLPReader(basedir);

                //Kalimdor takes a few seconds to load, and takes up about ~4xxMB of memory after its loaded, this can be much improved
                blp.LoadBLP("World\\Minimaps\\" + _SelectedMapName + "\\map" + x.ToString("D2") + "_" + y.ToString("D2") + ".blp");
                BitmapImage bitmapImage = new BitmapImage();
                using (MemoryStream bitmap = blp.asBitmapStream())
                {
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = bitmap;
                    bitmapImage.DecodePixelHeight = Convert.ToInt32(rect.Width);
                    bitmapImage.DecodePixelWidth = Convert.ToInt32(rect.Height);
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();
                }
                ImageBrush imgBrush = new ImageBrush(bitmapImage);
                rect.Fill = imgBrush;
            }
            else
            {
                rect.Fill = new SolidColorBrush(Color.FromRgb(0, 111, 0));
                Console.WriteLine(basedir + "World\\Minimaps\\" + _SelectedMapName + "\\map" + x.ToString("D2") + "_" + y.ToString("D2") + ".blp");
            }
            WDTGrid.Children.Add(rect);
        }
예제 #3
0
        public void LoadM2()
        {
            //Load model
            M2Reader reader = new M2Reader(basedir);
            string filename = modelPath;
            reader.LoadM2(filename);

            //Load vertices
            List<float> verticelist = new List<float>();
            for (int i = 0; i < reader.model.vertices.Count(); i++)
            {
                verticelist.Add(reader.model.vertices[i].position.X);
                verticelist.Add(reader.model.vertices[i].position.Z * -1);
                verticelist.Add(reader.model.vertices[i].position.Y);
                verticelist.Add(1.0f);
                verticelist.Add(reader.model.vertices[i].normal.X);
                verticelist.Add(reader.model.vertices[i].normal.Z * -1);
                verticelist.Add(reader.model.vertices[i].normal.Y);
                verticelist.Add(reader.model.vertices[i].textureCoordX);
                verticelist.Add(reader.model.vertices[i].textureCoordY);
            }

            //Load indices
            List<ushort> indicelist = new List<ushort>();
            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);
            }

            //Convert to array
            ushort[] indices = indicelist.ToArray();
            float[] vertices = verticelist.ToArray();

            //Get texture, what a mess this could be much better

            M2Material[] materials = new M2Material[reader.model.textures.Count()];
            for (int i = 0; i < reader.model.textures.Count(); i++)
            {
                materials[i].flags = reader.model.textures[i].flags;

                var blp = new BLPReader(basedir);
                if (File.Exists(Path.Combine(basedir, reader.model.filename.Replace("M2", "blp"))))
                {
                    blp.LoadBLP(reader.model.filename.Replace("M2", "blp"));
                }
                else
                {
                    blp.LoadBLP(reader.model.textures[i].filename);
                }

                if (blp.bmp == null)
                {
                    materials[i].texture = Texture2D.FromFile<Texture2D>(device, "missingtexture.jpg");
                }
                else
                {
                    MemoryStream s = new MemoryStream();
                    blp.bmp.Save(s, System.Drawing.Imaging.ImageFormat.Png);
                    s.Seek(0, SeekOrigin.Begin);
                    materials[i].texture = Texture2D.FromMemory<Texture2D>(device, s.ToArray());
                }
            }

            M2RenderBatch[] renderbatches = new M2RenderBatch[reader.model.skins[0].submeshes.Count()];
            for (int i = 0; i < reader.model.skins[0].submeshes.Count(); i++)
            {
                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].materialID = reader.model.skins[0].textureunit[tu].texture;
                    }
                }
            }

            m2.indices = indices;
            m2.vertices = vertices;
            m2.materials = materials;
            m2.renderBatches = renderbatches;
        }
예제 #4
0
        public static void exportWMO(string file, BackgroundWorker exportworker = null)
        {
            if(exportworker == null)
            {
                exportworker = new BackgroundWorker();
            }

            Console.WriteLine("Loading WMO file..");

            exportworker.ReportProgress(5, "Reading WMO..");

            var outdir = ConfigurationManager.AppSettings["outdir"];
            WMOReader reader = new WMOReader();
            reader.LoadWMO(file);

            // TODO: Support doodads!
            for (int i = 0; i < reader.wmofile.doodadNames.Count(); i++)
            {
                //Console.WriteLine(reader.wmofile.doodadNames[i].filename);
                //reader.wmofile.doodadDefinitions[i].
                //reader.wmofile.doodadDefinitions[i].
            }

            exportworker.ReportProgress(30, "Reading WMO..");

            uint totalVertices = 0;

            var groups = new Structs.WMOGroup[reader.wmofile.group.Count()];

            for (int g = 0; g < reader.wmofile.group.Count(); g++)
            {
                if (reader.wmofile.group[g].mogp.vertices == null) { continue; }
                for (int i = 0; i < reader.wmofile.groupNames.Count(); i++)
                {
                    if (reader.wmofile.group[g].mogp.nameOffset == reader.wmofile.groupNames[i].offset)
                    {
                        groups[g].name = reader.wmofile.groupNames[i].name.Replace(" ", "_");
                    }
                }

                if (groups[g].name == "antiportal") { continue; }

                groups[g].verticeOffset = totalVertices;
                groups[g].vertices = new Structs.Vertex[reader.wmofile.group[g].mogp.vertices.Count()];

                for (int i = 0; i < reader.wmofile.group[g].mogp.vertices.Count(); i++)
                {
                    groups[g].vertices[i].Position = new Vector3(reader.wmofile.group[g].mogp.vertices[i].vector.X * -1, reader.wmofile.group[g].mogp.vertices[i].vector.Z, reader.wmofile.group[g].mogp.vertices[i].vector.Y);
                    groups[g].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);
                    groups[g].vertices[i].TexCoord = new Vector2(reader.wmofile.group[g].mogp.textureCoords[0][i].X, reader.wmofile.group[g].mogp.textureCoords[0][i].Y);
                    totalVertices++;
                }

                var 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);
                }

                groups[g].indices = indicelist.ToArray();
            }

            exportworker.ReportProgress(55, "Exporting textures..");

            // Create output directory
            if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file))))
            {
                Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file)));
            }

            var mtlsb = new StringBuilder();
            var textureID = 0;

            var materials = new Structs.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].textureID = textureID + i;
                        materials[i].filename = Path.GetFileNameWithoutExtension(reader.wmofile.textures[ti].filename);
                        if (reader.wmofile.materials[i].blendMode == 0)
                        {
                            materials[i].transparent = false;
                        }
                        else
                        {
                            materials[i].transparent = true;
                        }

                        var blpreader = new BLPReader();

                        blpreader.LoadBLP(reader.wmofile.textures[ti].filename);

                        try
                        {
                            blpreader.bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(file), materials[i].filename + ".png"));
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }

                        textureID++;
                    }
                }
            }

            //No idea how MTL files really work yet. Needs more investigation.
            foreach (var material in materials)
            {
                mtlsb.Append("newmtl " + material.filename + "\n");
                mtlsb.Append("Ns 96.078431\n");
                mtlsb.Append("Ka 1.000000 1.000000 1.000000\n");
                mtlsb.Append("Kd 0.640000 0.640000 0.640000\n");
                mtlsb.Append("Ks 0.000000 0.000000 0.000000\n");
                mtlsb.Append("Ke 0.000000 0.000000 0.000000\n");
                mtlsb.Append("Ni 1.000000\n");
                mtlsb.Append("d 1.000000\n");
                mtlsb.Append("illum 2\n");
                mtlsb.Append("map_Kd " + material.filename + ".png\n");
                if (material.transparent)
                {
                    mtlsb.Append("map_d " + material.filename + ".png\n");
                }
            }

            File.WriteAllText(Path.Combine(outdir, file.Replace(".wmo", ".mtl")), mtlsb.ToString());

            exportworker.ReportProgress(75, "Exporting model..");

            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();
            }


            int rb = 0;
            for (int g = 0; g < reader.wmofile.group.Count(); g++)
            {
                groups[g].renderBatches = new Structs.RenderBatch[numRenderbatches];

                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];

                    groups[g].renderBatches[rb].firstFace = batch.firstFace;
                    groups[g].renderBatches[rb].numFaces = batch.numFaces;

                    if (batch.flags == 2)
                    {
                        groups[g].renderBatches[rb].materialID = (uint)batch.possibleBox2_3;
                    }
                    else
                    {
                        groups[g].renderBatches[rb].materialID = batch.materialID;
                    }
                    groups[g].renderBatches[rb].blendType = reader.wmofile.materials[batch.materialID].blendMode;
                    groups[g].renderBatches[rb].groupID = (uint)g;
                    rb++;
                }
            }

            exportworker.ReportProgress(95, "Writing files..");

            var objsw = new StreamWriter(Path.Combine(outdir, file.Replace(".wmo", ".obj")));
            objsw.WriteLine("# Written by Marlamin's WoW OBJExporter. Original file: " + file);
            objsw.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(file) + ".mtl");

            foreach (var group in groups)
            {
                if (group.vertices == null) { continue; }
                objsw.WriteLine("g " + group.name);

                foreach (var vertex in group.vertices)
                {
                    objsw.WriteLine("v " + vertex.Position.X + " " + vertex.Position.Y + " " + vertex.Position.Z);
                    objsw.WriteLine("vt " + vertex.TexCoord.X + " " + -vertex.TexCoord.Y);
                    objsw.WriteLine("vn " + vertex.Normal.X + " " + vertex.Normal.Y + " " + vertex.Normal.Z);
                }

                var indices = group.indices;

                foreach (var renderbatch in group.renderBatches)
                {
                    var i = renderbatch.firstFace;
                    if (renderbatch.numFaces > 0)
                    {
                        objsw.WriteLine("usemtl " + materials[renderbatch.materialID].filename);
                        objsw.WriteLine("s 1");
                        while (i < (renderbatch.firstFace + renderbatch.numFaces))
                        {
                            objsw.WriteLine("f " + (indices[i] + group.verticeOffset + 1) + "/" + (indices[i] + group.verticeOffset + 1) + "/" + (indices[i] + group.verticeOffset + 1) + " " + (indices[i + 1] + group.verticeOffset + 1) + "/" + (indices[i + 1] + group.verticeOffset + 1) + "/" + (indices[i + 1] + group.verticeOffset + 1) + " " + (indices[i + 2] + group.verticeOffset + 1) + "/" + (indices[i + 2] + group.verticeOffset + 1) + "/" + (indices[i + 2] + group.verticeOffset + 1));
                            i = i + 3;
                        }
                    }
                }
            }
            objsw.Close();
            Console.WriteLine("Done loading WMO file!");
        }
예제 #5
0
        public Render()
        {
            using (var dg = new DisposeGroup())
            {
                //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("TEXCOORD", 0, Format.R32G32_Float, 16, 0)
                }));

                //Load model
                M2Reader reader = new M2Reader("Z:\\18566_full\\");
                reader.LoadM2(@"World\ArtTest\Boxtest\xyz.m2");

                //Load vertices
                List<float> verticelist = new List<float>();
                for (int i = 0; i < reader.model.vertices.Count(); i++)
                {
                    verticelist.Add(reader.model.vertices[i].position.X);
                    verticelist.Add(reader.model.vertices[i].position.Z * -1);
                    verticelist.Add(reader.model.vertices[i].position.Y);
                    verticelist.Add(1.0f);
                    verticelist.Add(reader.model.vertices[i].textureCoordX);
                    verticelist.Add(reader.model.vertices[i].textureCoordY);
                }

                //Load indices
                List<ushort> indicelist = new List<ushort>();
                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);
                }

                //Convert to array
                ushort[] indices = indicelist.ToArray();
                float[] vertices = verticelist.ToArray();

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

                //Create buffers
                var vertexBuffer = dg.Add(Buffer.Create(Device, BindFlags.VertexBuffer, vertices));
                var vertexBufferBinding = new VertexBufferBinding(vertexBuffer, Utilities.SizeOf<Vector4>() + Utilities.SizeOf<Vector2>(), 0);
                var indexBuffer = dg.Add(Buffer.Create(Device, BindFlags.IndexBuffer, 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);

                //Get texture, what a mess this could be much better
                var blp = new BLPReader("Z:\\18566_full\\");
                if (File.Exists(Path.Combine("Z:\\18566_full\\", reader.model.filename.Replace("M2", "blp"))))
                {
                    blp.LoadBLP(reader.model.filename.Replace("M2", "blp"));
                }
                else
                {
                    if (reader.model.textures.Count() > 0)
                    {
                        blp.LoadBLP(reader.model.textures[0]);
                    }
                    else
                    {
                        throw new Exception("No forking textures, mate.");
                    }
                }

                MemoryStream s = new MemoryStream();
                blp.bmp.Save(s, System.Drawing.Imaging.ImageFormat.Png);
                s.Seek(0, SeekOrigin.Begin);
                Texture2D texture = Texture2D.FromMemory<Texture2D>(Device, s.ToArray());

                var textureView = new ShaderResourceView(Device, texture);

                var sampler = new SamplerState(Device, new SamplerStateDescription()
                {
                    Filter = Filter.MinMagMipLinear,
                    AddressU = TextureAddressMode.Wrap,
                    AddressV = TextureAddressMode.Wrap,
                    AddressW = TextureAddressMode.Wrap,
                    BorderColor = SharpDX.Color.Black,
                    ComparisonFunction = Comparison.Never,
                    MaximumAnisotropy = 16,
                    MipLodBias = 0,
                    MinimumLod = 0,
                    MaximumLod = 16,
                });

                Device.ImmediateContext.PixelShader.SetSampler(0, sampler);
                Device.ImmediateContext.PixelShader.SetShaderResource(0, textureView);
                //End of texture stuff,

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

            //Make camera
            Camera = new FirstPersonCamera();
            Camera.SetProjParams((float)Math.PI / 2, 1, 0.01f, 100.0f);
            Camera.SetViewParams(new Vector3(0.0f, 0.0f, -5.0f), new Vector3(0.0f, 1.0f, 0.0f));
        }
예제 #6
0
        public void LoadWMO()
        {
            WMOReader reader = new WMOReader(basedir);
            reader.LoadWMO(modelPath);

            WMOMaterial[] materials = new WMOMaterial[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)
                    {
                        Texture2D texture;
                        var blp = new BLPReader(basedir);
                        blp.LoadBLP(reader.wmofile.textures[ti].filename);
                        if (blp.bmp == null)
                        {
                            texture = Texture2D.FromFile<Texture2D>(device, "missingtexture.jpg");
                        }
                        else
                        {
                            MemoryStream s = new MemoryStream();
                            blp.bmp.Save(s, System.Drawing.Imaging.ImageFormat.Png);
                            s.Seek(0, SeekOrigin.Begin);
                            texture = Texture2D.FromMemory<Texture2D>(device, s.ToArray());
                            s.Dispose();
                        }
                        materials[i].materialID = (uint)i;
                        materials[i].filename = reader.wmofile.textures[ti].filename;
                        materials[i].texture = texture;
                    }
                }
            }

            WoWWMOGroup[] groups = new WoWWMOGroup[reader.wmofile.header.nGroups];

            for (int i = 0; i < reader.wmofile.header.nGroups; i++)
            {
                groups[i] = LoadGroupWMO(reader.wmofile.group[i]);
            }

            wmo.materials = materials;
            wmo.groups = groups;
        }
예제 #7
0
        public static void exportADT(string file, BackgroundWorker exportworker = null)
        {
            if (exportworker == null)
            {
                exportworker = new BackgroundWorker();
            }

            var outdir = ConfigurationManager.AppSettings["outdir"];

            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 /2 ends up being pixelspercoord on minimap
            float MapMidPoint = 32.0f / ChunkSize;

            var mapname = file.Replace("world\\maps\\", "").Substring(0, file.Replace("world\\maps\\", "").IndexOf("\\"));
            var coord = file.Replace("world\\maps\\" + mapname + "\\" + mapname, "").Replace(".adt", "").Split('_');

            var centerx = int.Parse(coord[1]);
            var centery = int.Parse(coord[2]);

            List<Structs.RenderBatch> renderBatches = new List<Structs.RenderBatch>();
            List<Structs.Vertex> verticelist = new List<Structs.Vertex>();
            List<int> indicelist = new List<Int32>();
            Dictionary<int, string> materials = new Dictionary<int, string>();

            var distance = 1;

            // Create output directory
            if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file))))
            {
                Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file)));
            }

            for (int y = centery; y < centery + distance; y++)
            {
                for (int x = centerx; x < centerx + distance; x++)
                {
                    var curfile = "world\\maps\\" + mapname + "\\" + mapname + "_" + x + "_" + y + ".adt";

                    if (!CASC.FileExists(file))
                    {
                        Console.WriteLine("File " + file + " does not exist");
                        continue;
                    }

                    exportworker.ReportProgress(0, "Loading ADT " + curfile);

                    ADTReader reader = new ADTReader();
                    reader.LoadADT(curfile);

                    // No chunks? Let's get the hell out of here
                    if (reader.adtfile.chunks == null)
                    {
                        continue;
                    }
                    if (CASC.FileExists("world\\maptextures\\" + mapname + "\\" + mapname + "_" + y + "_" + x + ".blp"))
                    {
                        materials.Add(materials.Count() + 1, "mat" + y.ToString() + x.ToString());

                        var blpreader = new BLPReader();

                        blpreader.LoadBLP(curfile.Replace("maps", "maptextures").Replace(".adt", ".blp"));

                        try
                        {
                            blpreader.bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(file), "mat" + y.ToString() + x.ToString() + ".png"));
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }
                    }

                    //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];

                    //    //if (!WoWFormatLib.Utils.CASC.FileExists(material.filename)) { continue; }

                    //    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;

                    for (uint c = 0; c < reader.adtfile.chunks.Count(); c++)
                    {
                        var chunk = reader.adtfile.chunks[c];

                        int off = verticelist.Count();

                        Structs.RenderBatch batch = new Structs.RenderBatch();

                        for (int i = 0, idx = 0; i < 17; i++)
                        {
                            for (int j = 0; j < (((i % 2) != 0) ? 8 : 9); j++)
                            {
                                Structs.Vertex v = new Structs.Vertex();
                                v.Normal = new OpenTK.Vector3(chunk.normals.normal_2[idx] / 127f, chunk.normals.normal_0[idx] / 127f, chunk.normals.normal_1[idx] / 127f);
                                v.Position = new OpenTK.Vector3(chunk.header.position.Y - (j * UnitSize), chunk.vertices.vertices[idx++] + chunk.header.position.Z, chunk.header.position.X - (i * UnitSize * 0.5f));
                                if ((i % 2) != 0) v.Position.X -= 0.5f * UnitSize;
                                v.TexCoord = new Vector2(-(v.Position.X - initialChunkX) / TileSize, -(v.Position.Z - 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.materialID = (uint)materials.Count();

                        batch.numFaces = (uint)(indicelist.Count()) - batch.firstFace;

                        //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);
                    }
                }
            }

            var mtlsw = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".mtl"));

            //No idea how MTL files really work yet. Needs more investigation.
            foreach (var material in materials)
            {
                mtlsw.WriteLine("newmtl " + material.Value);
                mtlsw.WriteLine("Ka 1.000000 1.000000 1.000000");
                mtlsw.WriteLine("Kd 0.640000 0.640000 0.640000");
                mtlsw.WriteLine("map_Ka " + material.Value + ".png");
                mtlsw.WriteLine("map_Kd " + material.Value + ".png");
            }

            mtlsw.Close();

            var indices = indicelist.ToArray();

            var adtname = Path.GetFileNameWithoutExtension(file);

            var objsw = new StreamWriter(Path.Combine(outdir, file.Replace(".adt", ".obj")));

            objsw.WriteLine("# Written by Marlamin's WoW OBJExporter. Original file: " + file);
            objsw.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".mtl");
            objsw.WriteLine("g " + adtname);

            foreach (var vertex in verticelist)
            {
                objsw.WriteLine("v " + vertex.Position.X + " " + vertex.Position.Y + " " + vertex.Position.Z);
                objsw.WriteLine("vt " + vertex.TexCoord.X + " " + -vertex.TexCoord.Y);
                objsw.WriteLine("vn " + vertex.Normal.X + " " + vertex.Normal.Y + " " + vertex.Normal.Z);
            }

            foreach (var renderBatch in renderBatches)
            {
                var i = renderBatch.firstFace;
                if (materials.ContainsKey((int)renderBatch.materialID)) { objsw.WriteLine("usemtl " + materials[(int)renderBatch.materialID]); objsw.WriteLine("s 1"); }
                while (i < (renderBatch.firstFace + renderBatch.numFaces))
                {
                    objsw.WriteLine("f " + (indices[i] + 1) + "/" + (indices[i] + 1) + "/" + (indices[i] + 1) + " " + (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + " " + (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1));
                    i = i + 3;
                }
            }

            objsw.Close();
        }
예제 #8
0
파일: WMO.cs 프로젝트: Ser0ja/WoWFormatTest
        private Bitmap CompileGroup(string wmoname, string groupid)
        {
            Console.WriteLine("  group " + groupid);
            int min_x = 64;
            int min_y = 64;

            int max_x = 0;
            int max_y = 0;

            int x = 0;
            int y = 0;

            string wmoonlyname = Path.GetFileNameWithoutExtension(wmoname);
            string wmodir = Path.GetDirectoryName(wmoname).Replace("World\\", "World\\Minimaps\\");
            List<string> filePaths = new List<string>();
            string lastpath = "";

            for (int cur_x = 0; cur_x < 64; cur_x++)
            {
                for (int cur_y = 0; cur_y < 64; cur_y++)
                {
                    string wmogroupfilename = wmodir + "\\" + wmoonlyname + "_" + groupid + "_" + cur_x.ToString().PadLeft(2, '0') + "_" + cur_y.ToString().PadLeft(2, '0') + ".blp";
                    //wmogroupfilename = wmogroupfilename.Replace("\\", "\\\\");
                    if (wmogroupfilename.Contains("000_00_00"))
                    {
                        Console.WriteLine("CHECKING " + wmogroupfilename);
                    }
                    if (CASC.FileExists(wmogroupfilename))
                    {
                        Console.WriteLine(wmogroupfilename + " exists!");
                        filePaths.Add(wmogroupfilename);
                    }
                }
            }

            foreach (string path in filePaths)
            {
                Console.WriteLine(path);
                x = int.Parse(path.Substring(path.Length - 9, 2));
                y = int.Parse(path.Substring(path.Length - 6, 2));

                if (x > max_x) { max_x = x; }
                if (y > max_y) { max_y = y; }

                if (x < min_x) { min_x = x; }
                if (y < min_y) { min_y = y; }

                // Console.WriteLine("[" + groupid + "] MIN: " + min_x + " " + min_y);
                // Console.WriteLine("[" + groupid + "] MAX: " + max_x + " " + max_y);

                lastpath = path;
            }
            var res_x = 0;
            var res_y = 0;

            if (min_x == 0 && max_x == 0 && min_y == 0 && max_y == 0)
            {
                var blpreader = new BLPReader();
                blpreader.LoadBLP(lastpath);
                res_x = blpreader.bmp.Width;
                res_y = blpreader.bmp.Height;
            }
            else
            {
                res_x = (((max_x - min_x) * 256) + 256);
                res_y = (((max_y - min_y) * 256) + 256);
            }

            //Console.WriteLine("[" + groupid + "] " + "Creating new image of " + res_x + "x" + res_y + " for " + wmoname);

            if (res_x < 0) { res_x = 1; }
            if (res_y < 0) { res_y = 1; }

            Bitmap bmp = new Bitmap(res_x, res_y);
            Graphics g = Graphics.FromImage(bmp);

            foreach (string path in filePaths)
            {
                x = int.Parse(path.Substring(path.Length - 9, 2));
                y = int.Parse(path.Substring(path.Length - 6, 2));
                var blpreader = new BLPReader();
                blpreader.LoadBLP(path);
                //  Console.WriteLine("BLP Width: " + blpreader.bmp.Width);
                //  Console.WriteLine("BLP Height: " + blpreader.bmp.Height);
                var draw_x = (x - min_x) * 256;
                var draw_y = (max_y - (y - min_y)) * 256;
                //Console.WriteLine("Drawing tile at " + draw_x + " & " + draw_y);
                g.DrawImage(blpreader.bmp, draw_x, draw_y, new Rectangle(0, 0, blpreader.bmp.Width, blpreader.bmp.Height), GraphicsUnit.Pixel);
            }

            g.Dispose();
            return bmp;
        }
예제 #9
0
        public static void exportM2(string file, BackgroundWorker exportworker = null)
        {
            if (exportworker == null)
            {
                exportworker = new BackgroundWorker();
            }

            var outdir = ConfigurationManager.AppSettings["outdir"];
            var reader = new M2Reader();

            exportworker.ReportProgress(15, "Reading M2..");

            if (!CASC.FileExists(file)) { throw new Exception("404 M2 not found!"); }

            reader.LoadM2(file);

            Structs.Vertex[] vertices = new Structs.Vertex[reader.model.vertices.Count()];

            for (int i = 0; i < reader.model.vertices.Count(); i++)
            {
                vertices[i].Position = new OpenTK.Vector3(reader.model.vertices[i].position.X, reader.model.vertices[i].position.Z, reader.model.vertices[i].position.Y * -1);
                vertices[i].Normal = new OpenTK.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);
            }

            // Create output directory
            if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file))))
            {
                Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file)));
            }

            var objsw = new StreamWriter(Path.Combine(outdir, file.Replace(".m2", ".obj")));

            objsw.WriteLine("# Written by Marlamin's WoW OBJExporter. Original file: " + file);
            objsw.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(file) + ".mtl");

            foreach (var vertex in vertices)
            {
                objsw.WriteLine("v " + vertex.Position.X + " " + vertex.Position.Y + " " + vertex.Position.Z);
                objsw.WriteLine("vt " + vertex.TexCoord.X + " " + -vertex.TexCoord.Y);
                objsw.WriteLine("vn " + vertex.Position.X + " " + vertex.Position.Y + " " + vertex.Normal.Z);
            }

            List<uint> indicelist = new List<uint>();
            for (int i = 0; i < reader.model.skins[0].triangles.Count(); i++)
            {
                var t = reader.model.skins[0].triangles[i];
                indicelist.Add(t.pt1);
                indicelist.Add(t.pt2);
                indicelist.Add(t.pt3);
            }

            var indices = indicelist.ToArray();
            exportworker.ReportProgress(35, "Writing files..");

            var renderbatches = new Structs.RenderBatch[reader.model.skins[0].submeshes.Count()];
            for (int i = 0; i < reader.model.skins[0].submeshes.Count(); i++)
            {
                if (file.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;
                        }
                    }
                }

                renderbatches[i].firstFace = reader.model.skins[0].submeshes[i].startTriangle;
                renderbatches[i].numFaces = reader.model.skins[0].submeshes[i].nTriangles;
                renderbatches[i].groupID = (uint)i;
                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;
                    }
                }
            }

            exportworker.ReportProgress(65, "Exporting textures..");

            var mtlsb = new StreamWriter(Path.Combine(outdir, file.Replace(".m2", ".mtl")));
            var textureID = 0;
            var materials = new Structs.Material[reader.model.textures.Count()];

            for (int i = 0; i < reader.model.textures.Count(); i++)
            {
                string texturefilename = "Dungeons\\Textures\\testing\\COLOR_13.blp";
                materials[i].flags = reader.model.textures[i].flags;
                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(file, (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(file, ".blp")))
                        {
                            //Console.WriteLine("      BLP exists!");
                            texturefilename = Path.ChangeExtension(file, ".blp");
                        }
                        else
                        {
                            //Console.WriteLine("      Type 2 does not exist!");
                            //needs lookup?
                        }
                        break;
                    case 11:
                        string[] cdifilenames = WoWFormatLib.DBC.DBCHelper.getTexturesByModelFilename(file, (int)reader.model.textures[i].type);
                        for (int ti = 0; ti < cdifilenames.Count(); ti++)
                        {
                            if (WoWFormatLib.Utils.CASC.FileExists(file.Replace(reader.model.name + ".M2", cdifilenames[ti] + ".blp")))
                            {
                                texturefilename = file.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 = textureID + i;
                materials[i].filename = Path.GetFileNameWithoutExtension(texturefilename);

                var blpreader = new BLPReader();

                blpreader.LoadBLP(texturefilename);

                try
                {
                    blpreader.bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(file), materials[i].filename + ".png"));
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }

            exportworker.ReportProgress(85, "Writing files..");

            foreach (var material in materials)
            {
                mtlsb.WriteLine("newmtl " + material.filename);
                mtlsb.WriteLine("illum 2");
                mtlsb.WriteLine("map_Ka " + material.filename + ".png");
                mtlsb.WriteLine("map_Kd " + material.filename + ".png");
            }

            mtlsb.Close();

            objsw.WriteLine("g " + Path.GetFileNameWithoutExtension(file));

            foreach (var renderbatch in renderbatches)
            {
                var i = renderbatch.firstFace;
                objsw.WriteLine("o " + Path.GetFileNameWithoutExtension(file) + renderbatch.groupID);
                objsw.WriteLine("usemtl " + materials[renderbatch.materialID].filename);
                objsw.WriteLine("s 1");
                while (i < (renderbatch.firstFace + renderbatch.numFaces))
                {
                    objsw.WriteLine("f " + (indices[i] + 1) + "/" + (indices[i] + 1) + "/" + (indices[i] + 1) + " " + (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + " " + (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1));
                    i = i + 3;
                }
            }

            objsw.Close();
            // https://en.wikipedia.org/wiki/Wavefront_.obj_file#Basic_materials
            // http://wiki.unity3d.com/index.php?title=ExportOBJ
            // http://web.cse.ohio-state.edu/~hwshen/581/Site/Lab3_files/Labhelp_Obj_parser.htm

            Console.WriteLine("Done loading model!");
        }
예제 #10
0
        private static void Main(string[] args)
        {
            string mapname = "";

            string basedir = ConfigurationManager.AppSettings["basedir"];
            bool buildmaps = Boolean.Parse(ConfigurationManager.AppSettings["buildmaps"]);
            bool buildWMOmaps = Boolean.Parse(ConfigurationManager.AppSettings["buildwmomaps"]);

            Console.WriteLine("Initializing CASC..");

            if(basedir != String.Empty){
                CASC.InitCasc(null, basedir);
            }else{
                CASC.InitCasc(null, @"D:\Games\World of Warcraft Public Test", "wow_beta"); // Use beta for now
            }

            Console.WriteLine("CASC initialized!");
            Console.WriteLine("Current patch: " + CASC.cascHandler.Config.BuildName);

            if (buildmaps == true)
            {
                DBCReader<MapRecord> reader = new DBCReader<MapRecord>("DBFilesClient\\Map.dbc");
                for (int i = 0; i < reader.recordCount; i++)
                {
                    //I used to check if WDT existed, but sometimes minimaps for maps without WDTs slip through the cracks
                    mapname = reader[i].Directory;

                    if (reader[i].expansionID < 6) { Console.WriteLine("Skipping map " + mapname + " WoD and below!"); continue; }

                    var min_x = 64;
                    var min_y = 64;

                    var max_x = 0;
                    var max_y = 0;

                    for (int cur_x = 0; cur_x < 64; cur_x++)
                    {
                        for (int cur_y = 0; cur_y < 64; cur_y++)
                        {
                            if (CASC.FileExists("World\\Minimaps\\" + mapname + "\\map" + cur_x + "_" + cur_y + ".blp"))
                            {
                                if (cur_x > max_x) { max_x = cur_x; }
                                if (cur_y > max_y) { max_y = cur_y; }

                                if (cur_x < min_x) { min_x = cur_x; }
                                if (cur_y < min_y) { min_y = cur_y; }
                            }
                        }
                    }

                    Console.WriteLine("[" + mapname + "] MIN: (" + min_x + " " + min_y + ") MAX: (" + max_x + " " + max_y + ")");

                    var res_x = (((max_x - min_x) * 256) + 256);
                    var res_y = (((max_y - min_y) * 256) + 256);

                    if (res_x < 0 || res_y < 0)
                    {
                        Console.WriteLine("[" + mapname + "] " + "Skipping map, has no minimap tiles");
                        continue;
                    }

                    Console.WriteLine("[" + mapname + "] " + "Creating new image of " + res_x + "x" + res_y);

                    Bitmap bmp = new Bitmap(res_x, res_y);
                    Graphics g = Graphics.FromImage(bmp);
                    Font drawFont = new Font("Arial", 16);

                    for (int cur_x = 0; cur_x < 64; cur_x++)
                    {
                        for (int cur_y = 0; cur_y < 64; cur_y++)
                        {
                            if (CASC.FileExists("World\\Minimaps\\" + mapname + "\\map" + cur_x + "_" + cur_y + ".blp"))
                            {
                                var blpreader = new BLPReader();
                                blpreader.LoadBLP("World\\Minimaps\\" + mapname + "\\map" + cur_x + "_" + cur_y + ".blp");
                                g.DrawImage(blpreader.bmp, (cur_x - min_x) * 256, (cur_y - min_y) * 256, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                            }
                        }
                    }
                    g.Dispose();
                    if (!Directory.Exists("done")) { Directory.CreateDirectory("done"); }
                    bmp.Save("done/" + mapname + ".png");

                    // SUPER MINIMAP COMPILER TIME!!!!!!!!!!!!!!!
                    var super_res_x = (((max_x - min_x) * 512) + 512);
                    var super_res_y = (((max_y - min_y) * 512) + 512);

                    if (super_res_x < 0 || super_res_y < 0)
                    {
                        Console.WriteLine("[SUPER " + mapname + "] " + "Skipping map, has no minimap tiles");
                        continue;
                    }

                    Console.WriteLine("[SUPER " + mapname + "] " + "Creating new image of " + super_res_x + "x" + super_res_y);

                    Bitmap super_bmp = new Bitmap(super_res_x, super_res_y);
                    Graphics super_g = Graphics.FromImage(super_bmp);

                    for (int cur_x = 0; cur_x < 64; cur_x++)
                    {
                        for (int cur_y = 0; cur_y < 64; cur_y++)
                        {
                            if (CASC.FileExists("World\\Minimaps\\" + mapname + "\\map" + cur_x + "_" + cur_y + ".blp"))
                            {
                                var blpreader = new BLPReader();
                                blpreader.LoadBLP("World\\Minimaps\\" + mapname + "\\map" + cur_x + "_" + cur_y + ".blp");
                                super_g.DrawImage(blpreader.bmp, (cur_x - min_x) * 512, (cur_y - min_y) * 512, new Rectangle(0, 0, 512, 512), GraphicsUnit.Pixel);
                            }
                        }
                    }
                    super_g.Dispose();
                    if (!Directory.Exists("done")) { Directory.CreateDirectory("done"); }
                    super_bmp.Save("done/SUPER_" + mapname + ".png");
                }
            }
                

            if (buildWMOmaps == true)
            {
                //List<string> listfile = CASC.GenerateListfile();
                var listfile = File.ReadAllLines(@"listfile.txt");
                DBCReader<MapRecord> reader = new DBCReader<MapRecord>("DBFilesClient\\Map.dbc");

                string[] unwantedExtensions = new string[513];
                for (int i = 0; i < 512; i++)
                {
                    unwantedExtensions[i] = "_" + i.ToString().PadLeft(3, '0') + ".wmo";
                }
                unwantedExtensions[512] = "LOD1.wmo";
                foreach (string s in listfile)
                {
                    if (!unwantedExtensions.Contains(s.Substring(s.Length - 8, 8)))
                    {
                        if (!s.Contains("LOD") && s.EndsWith(".wmo", StringComparison.CurrentCultureIgnoreCase))
                        {
                            Console.WriteLine(s);
                            WMO wmocompiler = new WMO();
                            wmocompiler.Compile(s);
                        }
                    }
                }
                Console.ReadLine();
            }
        }
예제 #11
0
        protected override void OnLoad(EventArgs e)
        {
            // Get OpenGL version
            Console.WriteLine("OpenGL version: " + GL.GetString(StringName.Version));
            Console.WriteLine("OpenGL vendor: " + GL.GetString(StringName.Vendor));

            this.CursorVisible = false;

            // Set up camera
            ActiveCamera = new OldCamera(Width, Height, new Vector3(0, 0, -1), new Vector3(0, 0, 1), Vector3.UnitY);

            // Vertex Attribute Object
            vertexAttribObject = GL.GenVertexArray();
            GL.BindVertexArray(vertexAttribObject);

            // Vertices
            float[] vertices = new float[] {
                    -1.0f, -1.0f, -10f, 0.0f, 0.0f, // Top-left
				     1.0f, -1.0f, -10f, 1.0f, 0.0f, // Top-right
				     1.0f, 1.0f, -10f, 1.0f, 1.0f, // Bottom-right
				    -1.0f, 1.0f, -10f, 0.0f, 1.0f  // Bottom-left
            };

            vertexBuffer = GL.GenBuffer();

            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);

            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (vertices.Count() * sizeof(float)), vertices, BufferUsageHint.StaticDraw);

            int verticeBufferSize = 0;

            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);
            GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out verticeBufferSize);

            Console.WriteLine("Vertices in buffer: " + verticeBufferSize / 5 / sizeof(float));

            // Elements
            int[] elements = new int[] {
                0, 1, 2,
                2, 3, 0
            };

            elementBuffer = GL.GenBuffer();

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementBuffer);
            GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(elements.Count() * sizeof(int)), elements, BufferUsageHint.StaticDraw);

            // Vertex shader
            vertexShader = GL.CreateShader(ShaderType.VertexShader);

            string vertexSource = File.ReadAllText("Shaders/vertex.shader");
            Console.WriteLine(vertexSource);
            GL.ShaderSource(vertexShader, vertexSource);

            GL.CompileShader(vertexShader);

            int vertexShaderStatus;
            GL.GetShader(vertexShader, ShaderParameter.CompileStatus, out vertexShaderStatus);
            Console.WriteLine("[VERTEX] Shader compile status: " + vertexShaderStatus);

            string vertexShaderLog;
            GL.GetShaderInfoLog(vertexShader, out vertexShaderLog);
            Console.Write(vertexShaderLog);

            // Fragment shader
            fragmentShader = GL.CreateShader(ShaderType.FragmentShader);

            string fragmentSource = File.ReadAllText("Shaders/fragment.shader");
            Console.WriteLine(fragmentSource);
            GL.ShaderSource(fragmentShader, fragmentSource);

            GL.CompileShader(fragmentShader);

            int fragmentShaderStatus;
            GL.GetShader(fragmentShader, ShaderParameter.CompileStatus, out fragmentShaderStatus);
            Console.WriteLine("[FRAGMENT] Shader compile status: " + fragmentShaderStatus);

            string fragmentShaderLog;
            GL.GetShaderInfoLog(fragmentShader, out fragmentShaderLog);
            Console.Write(fragmentShaderLog);

            // Shader program
            shaderProgram = GL.CreateProgram();
            GL.AttachShader(shaderProgram, vertexShader);
            GL.AttachShader(shaderProgram, fragmentShader);

            GL.BindFragDataLocation(shaderProgram, 0, "outColor");

            GL.LinkProgram(shaderProgram);
            string programInfoLog = GL.GetProgramInfoLog(shaderProgram);
            Console.Write(programInfoLog);

            int programStatus;
            GL.GetProgram(shaderProgram, GetProgramParameterName.LinkStatus, out programStatus);
            Console.WriteLine("[FRAGMENT] Program link status: " + programStatus);
            GL.UseProgram(shaderProgram);

            GL.ValidateProgram(shaderProgram);

            GL.DetachShader(shaderProgram, vertexShader);
            GL.DeleteShader(vertexShader);

            GL.DetachShader(shaderProgram, fragmentShader);
            GL.DeleteShader(fragmentShader);
            // Set up matrix
            ActiveCamera.setupGLRenderMatrix(shaderProgram);

            // Shader settings
            int posAttrib = GL.GetAttribLocation(shaderProgram, "position");
            GL.EnableVertexAttribArray(posAttrib);
            GL.VertexAttribPointer(posAttrib, 3, VertexAttribPointerType.Float, false, sizeof(float) * 5, 0);

            int texCoordAttrib = GL.GetAttribLocation(shaderProgram, "texCoord");
            GL.EnableVertexAttribArray(texCoordAttrib);
            GL.VertexAttribPointer(texCoordAttrib, 2, VertexAttribPointerType.Float, false, sizeof(float) * 5, sizeof(float) * 3);

            // Clear 
            GL.ClearColor(Color.Black);

            // Uniforms
            int uniColor = GL.GetUniformLocation(shaderProgram, "triangleColor");
            Vector3 uniCol3 = new Vector3(1.0f, 0.0f, 0.0f);
            GL.Uniform3(uniColor, uniCol3);

            // Textures
            int[] textureIds = new int[2];
            GL.GenTextures(2, textureIds);

            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, textureIds[0]);

            var blp = new BLPReader();

            blp.LoadBLP(File.OpenRead(@"Z:\WoW extracts\20363_full\Textures\ShaneCube.blp"));

            System.Drawing.Imaging.BitmapData bmp_data = blp.bmp.LockBits(new System.Drawing.Rectangle(0, 0, blp.bmp.Width, blp.bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);

            blp.bmp.UnlockBits(bmp_data);

            GL.Uniform1(GL.GetUniformLocation(shaderProgram, "tex"), 0);

            GL.ActiveTexture(TextureUnit.Texture1);
            GL.BindTexture(TextureTarget.Texture2D, textureIds[1]);

        }