void Read(EndianBinaryReader reader)
        {
            if (CurrentControl != null)
            {
                CurrentControl.Hide();

                CurrentControl.RemoveFromMainForm(MainForm);

                CurrentControl = null;
            }

            Cam = new Camera();

            ChunkTemplates = LoadTemplates();

            Chunks.Clear();

            int numChunkHeaders = reader.ReadInt32();

            int readerOffsetStorage = 4;

            for (int i = 0; i < numChunkHeaders; i++)
            {
                string chunkName = reader.ReadStringUntil('\0');

                reader.BaseStream.Position -= 1;

                int numChunks = reader.ReadInt32();

                int chunksOffset = reader.ReadInt32();

                readerOffsetStorage = (int)reader.BaseStream.Position;

                reader.BaseStream.Position = chunksOffset;

                if (chunkName == "RTBL")
                {
                    //Skip offset bank, which is a table of integers
                    reader.BaseStream.Position += 4 * numChunks;
                }

                for (int j = 0; j < numChunks; j++)
                {
                    Chunk newChunk = new Chunk();

                    newChunk.Read(reader, chunkName, ChunkTemplates);

                    Chunks.Add(newChunk);
                }

                reader.BaseStream.Position = readerOffsetStorage;
            }

            foreach (Chunk chunk in Chunks)
            {
                string chunkSearchString = chunk.ChunkType.Remove(chunk.ChunkType.Length - 1);

                EntityTemplate template = ChunkTemplates.Find(x => x.ChunkID.Contains(chunkSearchString));

                template.ReadSpecialProcess(chunk.Fields, Chunks);
            }

            UpdateTreeView();

            MainForm.ElementView.SelectedNode = MainForm.ElementView.Nodes[0];

            SelectedChunk = Chunks[0];

            Controls = LoadControls();

            IsListLoaded = true;
        }
        public void SetUpViewport()
        {
            //_programID = GL.CreateProgram();

            ////Create the Vertex and Fragment shader from file using our helper function
            //int vertShaderId, fragShaderId;
            //LoadShader("vs.glsl", ShaderType.VertexShader, _programID, out vertShaderId);
            //LoadShader("fs.glsl", ShaderType.FragmentShader, _programID, out fragShaderId);

            ////Deincriment the reference count on the shaders so that they don't exist until the context is destroyed.
            ////(Housekeeping really)
            //GL.DeleteShader(vertShaderId);
            //GL.DeleteShader(fragShaderId);

            ////This specifically tells OpenGL that we want to be able to refer to the "vertexPos" variable inside of the vs.glsl
            ////This allows us to later refer to it by specicic number.
            //GL.BindAttribLocation(_programID, (int)ShaderAttributeIds.Position, "vertexPos");

            ////Linking the shader tells OpenGL to finish compiling it or something. It's required. :P
            //GL.LinkProgram(_programID);

            ////Now that the program is linked we can get the identifier/location of the uniforms (by id) within the shader.
            //_uniformMVP = GL.GetUniformLocation(_programID, "modelview");
            //_uniformColor = GL.GetUniformLocation(_programID, "outputColor");

            ////More error checking
            //if (GL.GetError() != ErrorCode.NoError)
            //    Console.WriteLine(GL.GetProgramInfoLog(_programID));

            //CreateTimer();

            /* This stuff is done *once* per program load */

            //Generate a Program ID
            _programID = GL.CreateProgram();

            Console.WriteLine(_programID + Environment.NewLine);

            Cam = new Camera();

            //Create the Vertex and Fragment shader from file using our helper function
            int vertShaderId, fragShaderId;
            LoadShader("vs.glsl", ShaderType.VertexShader, _programID, out vertShaderId);
            LoadShader("fs.glsl", ShaderType.FragmentShader, _programID, out fragShaderId);

            Console.WriteLine(vertShaderId + Environment.NewLine);

            Console.WriteLine(fragShaderId + Environment.NewLine);

            //Deincriment the reference count on the shaders so that they don't exist until the context is destroyed.
            //(Housekeeping really)
            GL.DeleteShader(vertShaderId);
            GL.DeleteShader(fragShaderId);

            //This specifically tells OpenGL that we want to be able to refer to the "vertexPos" variable inside of the vs.glsl
            //This allows us to later refer to it by specicic number.
            GL.BindAttribLocation(_programID, (int)ShaderAttributeIds.Position, "vertexPos");

            //Linking the shader tells OpenGL to finish compiling it or something. It's required. :P
            GL.LinkProgram(_programID);

            //Now that the program is linked we can get the identifier/location of the uniforms (by id) within the shader.
            _uniformMVP = GL.GetUniformLocation(_programID, "modelview");
            _uniformColor = GL.GetUniformLocation(_programID, "col");

            Console.WriteLine(_uniformMVP + Environment.NewLine);

            Console.WriteLine(_uniformColor + Environment.NewLine);

            //More error checking
            if (GL.GetError() != ErrorCode.NoError)
                Console.WriteLine(GL.GetProgramInfoLog(_programID));

            //This just hooks winforms to draw our control.
            CreateTimer();

            Console.WriteLine("Timer Created" + Environment.NewLine);
        }