// Use this function to load images, objects, and shaders at the start
        void initProgram()
        {
            // Generate a buffer on the graphics card for VBO indices
            GL.GenBuffers(1, out ibo_elements);

            // Load two shaders, one for test squares and the other for textured sprites
            shaders.Add("default", new ShaderProgram("vs.glsl", "fs.glsl", true));
            shaders.Add("textured", new ShaderProgram("vs_tex.glsl", "fs_tex.glsl", true));

            // Declare that the shader we will use first is the textured sprite
            activeShader = "textured";

            // Initialize the lists of objects in the dictionary
            objects.Add(1, new List<GameObject>());
            objects.Add(2, new List<GameObject>());
            objects.Add(64, new List<GameObject>());

            // Create a new sprite here
            // In final compiled game, should actually make gameObjects here and create the sprites
            // inside those.  For now, Sprite and GameObject will be synonymous.
            Sprite tc = new Sprite();

            // Load one of our images (also try Black_Hole.png), bind it to tc
            textures.Add("LifeIcon.png", loadImage("LifeIcon.png", tc));
            tc.TextureID = textures["LifeIcon.png"];

            // Create a new GameObject
            Vector2 startPos = new Vector2(64, 64);
            Vector2[] spawn = new Vector2[] { new Vector2(0, 64), new Vector2(64, 64), new Vector2(64, 0) };
            
            float[] map = new float[] { 0f, 0f, Width, Height };
            GameObject objPlayer = new GameObject("Player", startPos, spawn, map, 10.0f, 2f, true, tc);

            // Add the sprite to our list of active Sprites
            objects[1].Add(objPlayer);

            //--------------- Create bricks ------------------------------
            // Create a new sprite here
            // In final compiled game, should actually make gameObjects here and create the sprites
            // inside those.  For now, Sprite and GameObject will be synonymous.
            Sprite bc = new Sprite();

            // Load one of our images (also try Black_Hole.png), bind it to tc
            textures.Add("Bricks.png", loadImage("Bricks.png", bc));
            bc.TextureID = textures["Bricks.png"];

            // Create a new GameObject
            Vector2 sPos2 = new Vector2(128, 64);
            Vector2[] spawnBrick = new Vector2[] { new Vector2(0, 128), new Vector2(128, 128), new Vector2(128, 0) };

            GameObject objBricks = new GameObject("Bricks", sPos2, spawnBrick, map, 0.0f, 0.0f, true, bc);

            // Add the sprite to our list of active Sprites
            objects[2].Add(objBricks);

            // Make some invisible walls
            int wallX = 0;
            int wallY = 0;
            textures.Add("NoImage.png", loadImage("NoImage.png", out wallX, out wallY, true));
            for (int i = 0; i < 1600; i += 64)
            {
                Sprite ws = new Sprite();
                ws.Width = wallX;
                ws.Height = wallY;
                ws.TextureID = textures["NoImage.png"];
                Vector2[] spawnWall = new Vector2[] { new Vector2(0, 64), new Vector2(64, 64), new Vector2(64, 0) };
                GameObject wall = new GameObject("Wall" + i.ToString(), new Vector2(i, 0f), spawnWall, map, 0f, 0f, true, ws);
                objects[2].Add(wall);
            }

            // Create a background
            Background bg = new Background();
            textures.Add("circuit.png", loadImage("CircuitBOTTOM.png", bg, true));
            bg.TextureID = textures["circuit.png"];
            BGs.Add(bg);

            // Create background tiles
            int tilesetSizeX = 0;
            int tilesetSizeY = 0;
            textures.Add("Tile_Set_2.png", loadImage("Tile_Set_2.png", out tilesetSizeX, out tilesetSizeY, true));
            for (int i = 0; i < 1600; i += 64)
            {
                BGTile bgt = new BGTile();
                bgt.Width = tilesetSizeX;
                bgt.Height = tilesetSizeY;
                bgt.TextureID = textures["Tile_Set_2.png"];
                bgt.Position = new Vector3(i/(float)Width, 0, 0);
                bgt.absPosition = new Vector3(i, 0, 0);
                bgt.index = new Vector2((i/64)%2 + 1, 1);
                bgt.tSize = 64;
                BGTiles.Add(bgt);
                // Update the matrix used to calculate the Sprite's visuals
                bgt.CalculateModelMatrix();
                // Offset it by our viewport matrix (for things like scrolling levels)
                bgt.ModelViewProjectionMatrix = bgt.ModelMatrix;// * ortho;
            }
        }
 // Another overload, does the same as above, but also takes the Background object we're loading
 // into as an argument, so that it can set the height and width of the sprite.
 int loadImage(string filename, Background bg, bool tile = false)
 {
     try
     {
         Bitmap file = new Bitmap(filename);
         bg.Width = file.Width;
         bg.Height = file.Height;
         return loadImage(file, tile);
     }
     catch (FileNotFoundException e)
     {
         return -1;
     }
 }