//constructor takes as inputs, the name of the object, spawn location, map details as an array of floats that holds the maps size, the speed of the object, acceleration of the object, and whether object has collision.
 //NOTE: vertexOffsets must be vertices in order, with the last vertex connecting to the first, and discludes the reference vertex
 //referenceCoord must be provided with X and Y values in context of map coordinates; vertexOffsets must be provided with X and Y values as offsets of referenceCoord
 public GameObject(String name, Vector2 referenceCoord, Vector2[] vertexOffsets, float[] inputmap, float ispeed, float acceleration, bool collision, Sprite spr)
 {
     sprite = spr;
     col = collision;
     objectname = name;
     baseSpeed = ispeed;
     speed = ispeed;
     acc = acceleration;
     map = new float[4];
     Array.Copy(inputmap, map, 4);
     if (collision)
     {
         GameObject.collision.Add(this);
     }
     Vector2[] spawnCoords = new Vector2[vertexOffsets.Length + 1];
     spawnCoords[0] = referenceCoord;
     //calculates coordinates based on offsets
     for (int i = 1; i < spawnCoords.Length; i++)
     {
         spawnCoords[i] = vertexOffsets[i - 1];
         spawnCoords[i].X += referenceCoord.X;
         spawnCoords[i].Y += referenceCoord.Y;
     }
     //tells user if spawn failed
     if (!spawn(spawnCoords))
     {
         //MessageBox.Show("Spawn failed.", "Could not spawn object, invalid coordinates.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
     }
 }
        // 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 Sprite object we're loading
 // into as an argument, so that it can set the height and width of the sprite.
 int loadImage(string filename, Sprite spr, bool tile = false)
 {
     try
     {
         Bitmap file = new Bitmap(filename);
         spr.Width = file.Width;
         spr.Height = file.Height;
         return loadImage(file, tile);
     }
     catch (FileNotFoundException e)
     {
         return -1;
     }
 }