Exemplo n.º 1
0
        private static void FullscreenMode()
        {
            int oldX      = 50;
            int oldY      = 50;
            int oldWidth  = 320;
            int oldHeight = 320;

            if (screensaver)
            {
                Glut.glutKeyboardFunc(new Glut.KeyboardCallback(ScreensaverKeyboard));
                Glut.glutPassiveMotionFunc(new Glut.PassiveMotionCallback(ScreensaverPassive));
                Glut.glutMouseFunc(new Glut.MouseCallback(ScreensaverMouse));
            }
            else
            {
                Glut.glutKeyboardFunc(new Glut.KeyboardCallback(Keyboard));
            }
            Glut.glutSetCursor(Glut.GLUT_CURSOR_NONE);

            oldX      = Glut.glutGet(Glut.GLUT_WINDOW_X);
            oldY      = Glut.glutGet(Glut.GLUT_WINDOW_Y);
            oldWidth  = Glut.glutGet(Glut.GLUT_WINDOW_WIDTH);
            oldHeight = Glut.glutGet(Glut.GLUT_WINDOW_HEIGHT);

            Glut.glutFullScreen();
        }
Exemplo n.º 2
0
 private static void WindowedMode()
 {
     Glut.glutKeyboardFunc(new Glut.KeyboardCallback(Keyboard));
     Glut.glutPassiveMotionFunc(null);
     Glut.glutMouseFunc(null);
     Glut.glutSetCursor(Glut.GLUT_CURSOR_INHERIT);
     Glut.glutPositionWindow(50, 50);
     Glut.glutReshapeWindow(320, 320);
 }
Exemplo n.º 3
0
        static void RegisterFuncs()
        {
            int[] sceneKeys    = { Glut.GLUT_KEY_UP, Glut.GLUT_KEY_DOWN, Glut.GLUT_KEY_LEFT, Glut.GLUT_KEY_RIGHT };
            int[] airplaneKeys = { Glut.GLUT_KEY_F1, Glut.GLUT_KEY_F2, Glut.GLUT_KEY_F3, Glut.GLUT_KEY_F4 };
            int[] towerskeys   = { Glut.GLUT_KEY_F5 };

            KeyboardHandler.RegisterMethod(scene.KeyboardHandler, sceneKeys);
            KeyboardHandler.RegisterMethod(airplane.KeyboardHandler, airplaneKeys);
            KeyboardHandler.RegisterMethod(Scene.towersGroup.KeyboardHandler, towerskeys);

            Glut.glutPassiveMotionFunc(airplane.MouseHandler);

            Glut.glutSpecialFunc(KeyboardHandler.Handler);
        }
Exemplo n.º 4
0
        public void SetMainLoop()
        {
            //отлов действий пользователя
            Glut.glutMotionFunc(ClickedMotion);
            Glut.glutMouseFunc(Mouse);
            Glut.glutPassiveMotionFunc(PassiveMotion);
            Glut.glutKeyboardFunc(Key);
            Glut.glutKeyboardUpFunc(KeyUp);
            Glut.glutSpecialFunc(KeySpecial);
            Glut.glutSpecialUpFunc(KeySpecialUp);

            //старт игрового цикла
            Glut.glutTimerFunc(Config.TimePerFrame, MainProcess, 0);
            Glut.glutMainLoop();
        }
Exemplo n.º 5
0
 static void Main()
 {
     Glut.glutInit();
     Glut.glutSetOption(Glut.GLUT_MULTISAMPLE, 8);
     Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_RGBA | Glut.GLUT_DEPTH | Glut.GLUT_MULTISAMPLE);
     Glut.glutInitWindowSize(Globals.defaultwindowwidth, Globals.defaultwindowheight);
     Glut.glutCreateWindow("Marvis Console");
     init_graphics();
     Glut.glutDisplayFunc(on_display);
     Glut.glutPassiveMotionFunc(on_mousemove);
     Glut.glutMotionFunc(on_mousemove);
     Glut.glutMouseFunc(on_mouseclick);
     Glut.glutMouseWheelFunc(on_mousewheel);
     Glut.glutIdleFunc(idle);
     Glut.glutReshapeFunc(on_reshape);
     Glut.glutMainLoop();
 }
Exemplo n.º 6
0
        static void Main(string[] args)
        {
            Glut.glutInit();
            Initialisation_3D();
            Glut.glutReshapeFunc(On_Changement_Taille_Fenetre);
            Glut.glutDisplayFunc(Afficher_Ma_Scene);
            Glut.glutKeyboardFunc(Gestion_Clavier);
            Glut.glutSpecialFunc(Gestion_Touches_Speciales);
            Glut.glutIdleFunc(Animation_Scene);
            Glut.glutMouseFunc(Gestion_Bouton_Souris);
            Glut.glutMouseWheelFunc(Gestion_Molette);
            Glut.glutPassiveMotionFunc(Gestion_Souris_Libre);
            Glut.glutMotionFunc(Gestion_Souris_Clique);

            Initialisation_Animation();
            Glut.glutMainLoop();
        }
Exemplo n.º 7
0
        private static void Initialize()
        {
            Console.WriteLine("Controls:");                                 // Print Input Help
            Console.WriteLine("W: Move Forward");
            Console.WriteLine("A: Move Left");
            Console.WriteLine("S: Move Backward");
            Console.WriteLine("D: Move Right");
            Console.WriteLine("Mouse Controls View");
            Console.WriteLine("ESC: Exit");

            Alut.alutInit();                                                // Initialize OpenAL

            Glut.glutInit();                                                // Initialize GLUT
            // Set GL Context Properties
            Glut.glutInitDisplayMode(Glut.GLUT_DEPTH | Glut.GLUT_DOUBLE | Glut.GLUT_RGB);
            Glut.glutInitWindowSize(640, 480);                          // Set Window Size
            Glut.glutCreateWindow("OpenAL Tutorial");                   // Create Window

            Glut.glutDisplayFunc(new Glut.DisplayCallback(Display));    // Display Delegate
            Glut.glutKeyboardFunc(new Glut.KeyboardCallback(Keyboard)); // Keyboard Delegate
            Glut.glutIdleFunc(new Glut.IdleCallback(Idle));             // Idle Delegate
            // Mouse Movement Delegate
            Glut.glutPassiveMotionFunc(new Glut.PassiveMotionCallback(Mouse));
            Glut.glutReshapeFunc(new Glut.ReshapeCallback(Reshape));        // Window Resize Delegate

            LoadLevel();                                                    // Load The Level
            LoadWater();                                                    // Load The Water
            LoadCollision();                                                // Load The Collision Map
            xPosition = 3.0f;                                               // Set Our Initial Player Position
            yPosition = 1.0f;
            zPosition = 5.0f;
            LoadSounds();                                                   // Load The Sounds
            LoadTextures();                                                 // Load The Textures
            Gl.glEnable(Gl.GL_TEXTURE_2D);                                  // Enable Texture Mapping
            Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE);                     // Set The Blending Function For Translucency
            Gl.glClearColor(0.0f, 0.8f, 1.0f, 0.0f);                        // Clear Background Color To A Turquiose Blueish Color
            Gl.glClearDepth(1.0);                                           // Enables Clearing Of The Depth Buffer
            Gl.glDepthFunc(Gl.GL_LESS);                                     // The Type Of Depth Test To Do
            Gl.glEnable(Gl.GL_DEPTH_TEST);                                  // Enables Depth Testing
            Gl.glShadeModel(Gl.GL_SMOOTH);                                  // Enables Smooth Color Shading
            Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);     // Really Nice Perspective Calculations

            oldTime = currentTime = Environment.TickCount;                  // Initialize The Timer
        }
Exemplo n.º 8
0
        static void Main()
        {
            // create an OpenGL window
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
            Glut.glutInitWindowSize(width, height);
            Glut.glutCreateWindow("OpenGL UI: Example 1");

            // provide the Glut callbacks that are necessary for running this tutorial
            Glut.glutIdleFunc(OnRenderFrame);
            Glut.glutDisplayFunc(() => { });    // only here for mac os x
            Glut.glutCloseFunc(OnClose);
            Glut.glutMouseFunc(OnMouseClick);
            Glut.glutMotionFunc(OnMouseMove);
            Glut.glutPassiveMotionFunc(OnMouseMove);
            Glut.glutReshapeFunc(OnResize);
            Glut.glutKeyboardFunc(OnKeyboard);

            // enable depth testing to ensure correct z-ordering of our fragments
            Gl.Enable(EnableCap.DepthTest);
            Gl.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

            // initialize the user interface
            OpenGL.UI.UserInterface.InitUI(width, height);

            // create some centered text
            OpenGL.UI.Text welcome = new OpenGL.UI.Text(OpenGL.UI.Text.FontSize._24pt, "Welcome to OpenGL", OpenGL.UI.BMFont.Justification.Center);
            welcome.RelativeTo = OpenGL.UI.Corner.Center;

            // create some colored text
            OpenGL.UI.Text coloredText = new OpenGL.UI.Text(OpenGL.UI.Text.FontSize._24pt, "using C#", OpenGL.UI.BMFont.Justification.Center);
            coloredText.Position   = new Point(0, -30);
            coloredText.Color      = new Vector3(0.2f, 0.3f, 1f);
            coloredText.RelativeTo = OpenGL.UI.Corner.Center;

            // add the two text object to the UI
            OpenGL.UI.UserInterface.AddElement(welcome);
            OpenGL.UI.UserInterface.AddElement(coloredText);

            // enter the glut main loop (this is where the drawing happens)
            Glut.glutMainLoop();
        }
Exemplo n.º 9
0
        static void Main()
        {
            Glut.glutInit();

            Glut.glutInitDisplayMode(Glut.GLUT_SINGLE | Glut.GLUT_RGB);
            Glut.glutInitWindowSize(500, 300);
            Glut.glutInitWindowPosition(10, 10);
            Glut.glutCreateWindow("PONG");
            Inicializa();
            Glut.glutPassiveMotionFunc(rend.MoveMouse);
            Glut.glutTimerFunc(33, Timer, 1);
            Glut.glutDisplayFunc(rend.Desenha);
            Glut.glutReshapeFunc(AlteraTamanhoJanela);
            Glut.glutKeyboardFunc(evento.GerenciaTeclado);
            Glut.glutSpecialFunc(TeclasEspeciais);



            Glut.glutMainLoop();
        }
Exemplo n.º 10
0
        public static void Init()
        {
            Keys              = new bool[255];
            KeysTyped         = new bool[255];
            SpecialKeys       = new bool[255];
            Mouse             = new bool[3];
            KeysTypedCooldown = new CooldownTimer[255];
            for (int i = 0; i < KeysTypedCooldown.Length; i++)
            {
                KeysTypedCooldown[i] = new CooldownTimer(3);
            }

            Glut.glutKeyboardFunc(OnKeyboardDown);
            Glut.glutKeyboardUpFunc(OnKeyboardUp);
            Glut.glutSpecialFunc(OnSpecialDown);
            Glut.glutSpecialUpFunc(OnSpecialUp);
            Glut.glutMouseFunc(OnMousePress);
            Glut.glutMotionFunc(OnMouseMove);
            Glut.glutPassiveMotionFunc(OnMouseMove);
            Glut.glutMouseWheelFunc(OnMouseScroll);
        }
Exemplo n.º 11
0
        static void Main(string[] args)
        {
            Glut.glutInit();

/* need both double buffering and z buffer */

            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_RGB | Glut.GLUT_DEPTH);
            Glut.glutInitWindowSize(640, 480);
            Glut.glutCreateWindow("OpenGL");
            myInit();
            //mdlviewer_init( "homer.mdl", modelo.homer);
            Glut.glutReshapeFunc(myReshape);
            Glut.glutDisplayFunc(display);
            Glut.glutKeyboardFunc(keyboard);
            Glut.glutSpecialFunc(specialKey);
            Glut.glutMouseFunc(mouse);
            Glut.glutPassiveMotionFunc(mouse);



            imprime_ajuda();

            Glut.glutMainLoop();
        }
Exemplo n.º 12
0
        static void Main(string[] args)
        {
            while (true)
            {
                try
                {
                    Console.WriteLine("Input the number of levels to recurse. Must be greater than or equal to zero.\r\n" +
                                      "Mouse to look and WASD to move. Hold R to run. F to toggle fullscreen.\r\n" +
                                      "O to toggle between walking and flying. When flying, use E/Q to ascend/descend.");
                    if ((levelNum = Convert.ToInt32(Console.ReadLine())) >= 0)
                    {
                        break;
                    }
                }
                catch
                {
                    Console.WriteLine("Please input an integer greater than or equal to zero.");
                }
            }

            // init GLUT and create window
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH | Glut.GLUT_MULTISAMPLE);   // multisampling purportedly "makes things beautiful!"
            Glut.glutInitWindowSize(width, height);
            Glut.glutCreateWindow("Fractal");

            // register main loop callbacks
            Glut.glutDisplayFunc(renderScene);
            Glut.glutIdleFunc(idle);
            Glut.glutCloseFunc(onClose);

            //register resize callback
            Glut.glutReshapeFunc(OnReshape);

            // register keyboard callbacks
            Glut.glutKeyboardFunc(OnKeyboardDown);
            Glut.glutKeyboardUpFunc(OnKeyboardUp);

            // register mouse callbacks
            Glut.glutMotionFunc(OnMove);
            Glut.glutPassiveMotionFunc(OnMove);

            //hide mouse
            Glut.glutSetCursor(Glut.GLUT_CURSOR_NONE);

            //enable depth testing
            Gl.Enable(EnableCap.DepthTest);

            //enable alpha blending
            Gl.Enable(EnableCap.Blend);
            Gl.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

            //compile shader
            program = new ShaderProgram(VertexShader, FragmentShader);

            //make a camera
            camera = new Camera(new Vector3(0, 0, 0), Quaternion.Identity); //set the camera starting location here
            camera.SetDirection(new Vector3(0, 0, -1));

            // set the view and projection matrix
            program.Use();
            program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.90f, (float)width / height, 0.01f, 1000f));

            program["light_direction"].SetValue(new Vector3(-0.3f, -0.8f, -0.7f));  //pink
            program["light2_direction"].SetValue(new Vector3(0.7f, -0.8f, 0.3f));   //cyan
            program["light3_direction"].SetValue(new Vector3(0.3f, -0.8f, 0.7f));   //celadon
            program["light4_direction"].SetValue(new Vector3(-0.7f, -0.8f, -0.3f)); //yellow
            program["enable_lighting"].SetValue(lighting);

            //set background color
            Gl.ClearColor(0.99f, 0.93f, 0.85f, 1f);

            // load each block's model and decomposition rule from files and add to blockRef
            int fCount = Directory.GetFiles("assets", "*", SearchOption.TopDirectoryOnly).Length;

            for (int n = 0; n < fCount / 2; ++n)
            {
                List <Vector3> indexVertices = new List <Vector3>();
                List <Vector3> indexNormals  = new List <Vector3>();
                List <Vector3> vertices      = new List <Vector3>();
                List <Vector3> normals       = new List <Vector3>();
                List <Vector3> edgeVertices  = new List <Vector3>();

                StreamReader sr = new StreamReader("assets/" + n.ToString() + ".txt");
                while (!sr.EndOfStream)
                {
                    string[] fields = sr.ReadLine().Split();
                    if (fields[0] == "v") //a vertex
                    {
                        Vector3 vertex = new Vector3(Convert.ToSingle(fields[1]), Convert.ToSingle(fields[2]), Convert.ToSingle(fields[3]));
                        indexVertices.Add(vertex);
                    }
                    else if (fields[0] == "vn") //a vertex normal
                    {
                        Vector3 normal = new Vector3(Convert.ToSingle(fields[1]), Convert.ToSingle(fields[2]), Convert.ToSingle(fields[3]));
                        indexNormals.Add(normal);
                    }
                    else if (fields[0] == "f") //a face
                    {
                        for (int i = 1; i < fields.Length; ++i)
                        {
                            string[] indices = fields[i].Split('/');
                            vertices.Add(indexVertices[Convert.ToInt32(indices[0]) - 1]);
                            normals.Add(indexNormals[Convert.ToInt32(indices[2]) - 1]);
                        }
                    }
                    else if (fields[0] == "l") //an edge
                    {
                        edgeVertices.Add(indexVertices[Convert.ToInt32(fields[1]) - 1]);
                        edgeVertices.Add(indexVertices[Convert.ToInt32(fields[2]) - 1]);
                    }
                }
                sr.Close();

                //create the block object
                Block newBlock = new Block();
                newBlock.position     = new Vector3(0, 0, 0);
                newBlock.yOrientation = 0;
                newBlock.scale        = new Vector3(1, 1, 1);
                newBlock.ID           = n;

                //fill the block object with data loaded from .obj above
                newBlock.verticeData = vertices.ToArray();
                newBlock.normalData  = normals.ToArray();

                newBlock.edgeVerticeData = edgeVertices.ToArray();

                blockRef.Add(newBlock);

                //load the decomposition rule for this block
                List <DecompBlock> newDRule = new List <DecompBlock>();
                float scaleConst            = 1;
                float unitConst             = 1;

                sr = new StreamReader("assets/" + n.ToString() + "rule.txt");
                while (!sr.EndOfStream)
                {
                    string[] fields = sr.ReadLine().Split();
                    if (fields[0] != "#") //check its not a comment
                    {
                        if (fields[0] == "!")
                        {
                            //setting scale down values. e.g. if set to 1/3 and 2/3, each new block would be scaled down
                            //by 1/3, and each 1 unit offset written in the rule file would be scaled to move the block 2/3 units instead.
                            //default 1 and 1: no scaling applied.
                            scaleConst = Convert.ToSingle(fields[1]);
                            unitConst  = Convert.ToSingle(fields[2]);
                        }
                        else
                        {
                            //load in fields
                            DecompBlock newDBlock = new DecompBlock();
                            newDBlock.ID             = Convert.ToInt32(fields[0]);
                            newDBlock.posOffset      = new Vector3(Convert.ToSingle(fields[1]), Convert.ToSingle(fields[2]), Convert.ToSingle(fields[3]));
                            newDBlock.xAngleOffset   = Convert.ToSingle(fields[4]);
                            newDBlock.extraScale     = new Vector3(1, 1, 1);
                            newDBlock.unitScaleConst = unitConst;
                            newDBlock.scaleDownConst = scaleConst;
                            if (fields.Length > 5)
                            {
                                newDBlock.extraScale = new Vector3(Convert.ToInt32(fields[5]), Convert.ToInt32(fields[6]), Convert.ToInt32(fields[7]));
                            }

                            //add block to rule
                            newDRule.Add(newDBlock);
                        }
                    }
                }
                sr.Close();

                decompRules.Add(newDRule);
            }

            Block seedBlock = blockRef[0];

            blocks = Decompose(seedBlock, levelNum);

            //merge all vertices and normals into a an interleaved vbo
            List <Vector3> preVertices = new List <Vector3>();
            List <Vector3> preNormals  = new List <Vector3>();
            List <Vector3> preEdges    = new List <Vector3>();

            foreach (Block block in blocks)
            {
                foreach (Vector3 point in block.verticeData)
                {
                    Vector4 preVertex = (new Vector4(point, 1)
                                         * Matrix4.CreateScaling(block.scale)
                                         * Matrix4.CreateRotationY(block.yOrientation)
                                         + new Vector4(block.position, 1));
                    preVertices.Add(new Vector3(preVertex.Get(0), preVertex.Get(1), preVertex.Get(2)));
                }

                foreach (Vector3 normal in block.normalData)
                {
                    Vector4 preNormal = (new Vector4(normal, 1)
                                         * Matrix4.CreateScaling(new Vector3(Math.Sign(block.scale[0]),
                                                                             Math.Sign(block.scale[1]),
                                                                             Math.Sign(block.scale[2])))
                                         * Matrix4.CreateRotationY(block.yOrientation));

                    preNormals.Add(new Vector3(Convert.ToSingle(Math.Round(preNormal.Get(0))),
                                               Convert.ToSingle(Math.Round(preNormal.Get(1))),
                                               Convert.ToSingle(Math.Round(preNormal.Get(2)))));
                }

                foreach (Vector3 point in block.edgeVerticeData)
                {
                    Vector4 preVertex = (new Vector4(point, 1)
                                         * Matrix4.CreateScaling(block.scale)
                                         * Matrix4.CreateRotationY(block.yOrientation)
                                         + new Vector4(block.position, 1));
                    preEdges.Add(new Vector3(preVertex.Get(0), preVertex.Get(1), preVertex.Get(2)));
                }
            }

            //exportOBJ(preVertices, preNormals); //exports fractal if left uncommented

            drawVertices = new VBO <Vector3>(preVertices.ToArray());
            drawNormals  = new VBO <Vector3>(preNormals.ToArray());
            drawEdges    = new VBO <Vector3>(preEdges.ToArray());

            List <uint> drawOrder = new List <uint>();

            for (int x = 0; x < preVertices.Count; ++x)
            {
                drawOrder.Add(Convert.ToUInt32(x));
            }
            drawElements = new VBO <uint>(drawOrder.ToArray(), BufferTarget.ElementArrayBuffer);

            drawOrder.Clear();
            for (int x = 0; x < preEdges.Count; ++x)
            {
                drawOrder.Add(Convert.ToUInt32(x));
            }
            drawEdgeElements = new VBO <uint>(drawOrder.ToArray(), BufferTarget.ElementArrayBuffer);

            watch = System.Diagnostics.Stopwatch.StartNew();

            // enter GLUT event processing cycle
            Glut.glutMainLoop();
        }
Exemplo n.º 13
0
        static void Main()
        {
            // create an OpenGL window
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
            Glut.glutInitWindowSize(width, height);
            Glut.glutCreateWindow("OpenGL UI: Example 2");

            // provide the Glut callbacks that are necessary for running this tutorial
            Glut.glutIdleFunc(OnRenderFrame);
            Glut.glutDisplayFunc(() => { });    // only here for mac os x
            Glut.glutCloseFunc(OnClose);
            Glut.glutMouseFunc(OnMouseClick);
            Glut.glutMotionFunc(OnMouseMove);
            Glut.glutPassiveMotionFunc(OnMouseMove);
            Glut.glutReshapeFunc(OnResize);
            Glut.glutKeyboardFunc(OnKeyboard);

            // enable depth testing to ensure correct z-ordering of our fragments
            Gl.Enable(EnableCap.DepthTest);
            Gl.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

            // initialize the user interface
            OpenGL.UI.UserInterface.InitUI(width, height);

            // create some centered text
            OpenGL.UI.Text selectText = new OpenGL.UI.Text(OpenGL.UI.Text.FontSize._24pt, "Select A Character", OpenGL.UI.BMFont.Justification.Center);
            selectText.Position   = new Point(0, 50);
            selectText.RelativeTo = OpenGL.UI.Corner.Center;

            OpenGL.UI.Text characterName = new OpenGL.UI.Text(OpenGL.UI.Text.FontSize._16pt, "", OpenGL.UI.BMFont.Justification.Center);
            characterName.RelativeTo = OpenGL.UI.Corner.Center;
            characterName.Position   = new Point(0, -70);

            // add the two text object to the UI
            OpenGL.UI.UserInterface.AddElement(selectText);
            OpenGL.UI.UserInterface.AddElement(characterName);

            // the license for these icons is located in the data folder
            string[] characters = new string[] { "boy.png", "man.png", "girl1.png", "girl2.png", "girl3.png" };
            textures = new Texture[characters.Length];
            int xoffset = -characters.Length * 80 / 2 + 40;

            for (int i = 0; i < characters.Length; i++)
            {
                string character = characters[i];

                // load a texture that will be used by a button
                textures[i] = new Texture(string.Format("data/{0}", character));

                // create buttons in a row, each of which uses a Texture (the Texture gives the initial size of the Button in pixels)
                OpenGL.UI.Button button = new OpenGL.UI.Button(textures[i]);
                button.Position   = new Point(xoffset, 5);
                button.RelativeTo = OpenGL.UI.Corner.Center;

                // change the color of the button when entering/leaving/clicking with the mouse
                button.OnMouseEnter = (sender, e) => button.BackgroundColor = new Vector4(0, 1f, 0.2f, 1.0f);
                button.OnMouseLeave = (sender, e) => button.BackgroundColor = Vector4.Zero;
                button.OnMouseDown  = (sender, e) => button.BackgroundColor = new Vector4(0, 0.6f, 1f, 1f);
                button.OnMouseUp    = (sender, e) => button.BackgroundColor = (OpenGL.UI.UserInterface.Selection == button ? new Vector4(0, 1f, 0.2f, 1.0f) : Vector4.Zero);

                // update the text with the character name when the button is clicked
                button.OnMouseClick = (sender, e) => characterName.String = string.Format("You selected {0}!", character);

                OpenGL.UI.UserInterface.AddElement(button);

                xoffset += 80;
            }

            // enter the glut main loop (this is where the drawing happens)
            Glut.glutMainLoop();
        }