// This code was written for the OpenTK library and has been released // to the Public Domain. // It is provided "as is" without express or implied warranty of any kind. #region --- Using directives --- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Diagnostics; using System.Threading; using OpenTK.Graphics.OpenGL; using OpenTK.Platform; using OpenTK; #endregion namespace Examples.WinForms { [Example("Simple GLControl Game Loop", ExampleCategory.OpenTK, "GLControl", 2, Documentation="GLControlGameLoop")] public partial class GameLoopForm : Form { static float angle = 0.0f; #region --- Constructor --- public GameLoopForm() { InitializeComponent(); } #endregion #region OnLoad protected override void OnLoad(EventArgs e) { base.OnLoad(e); glControl.KeyDown += new KeyEventHandler(glControl_KeyDown); glControl.KeyUp += new KeyEventHandler(glControl_KeyUp); glControl.Resize += new EventHandler(glControl_Resize); glControl.Paint += new PaintEventHandler(glControl_Paint); Text = GL.GetString(StringName.Vendor) + " " + GL.GetString(StringName.Renderer) + " " + GL.GetString(StringName.Version); GL.ClearColor(Color.MidnightBlue); GL.Enable(EnableCap.DepthTest); Application.Idle += Application_Idle; // Ensure that the viewport and projection matrix are set correctly. glControl_Resize(glControl, EventArgs.Empty); } void glControl_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.F12) { GrabScreenshot().Save("screenshot.png"); } } #endregion #region OnClosing protected override void OnClosing(CancelEventArgs e) { Application.Idle -= Application_Idle; base.OnClosing(e); } #endregion #region Application_Idle event void Application_Idle(object sender, EventArgs e) { while (glControl.IsIdle) { Render(); } } #endregion #region GLControl.Resize event handler void glControl_Resize(object sender, EventArgs e) { OpenTK.GLControl c = sender as OpenTK.GLControl; if (c.ClientSize.Height == 0) c.ClientSize = new System.Drawing.Size(c.ClientSize.Width, 1); GL.Viewport(0, 0, c.ClientSize.Width, c.ClientSize.Height); float aspect_ratio = Width / (float)Height; Matrix4 perpective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspect_ratio, 1, 64); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref perpective); } #endregion #region GLControl.KeyDown event handler void glControl_KeyDown(object sender, KeyEventArgs e) { switch (e.KeyData) { case Keys.Escape: this.Close(); break; } } #endregion #region GLControl.Paint event handler void glControl_Paint(object sender, PaintEventArgs e) { Render(); } #endregion #region private void Render() private void Render() { Matrix4 lookat = Matrix4.LookAt(0, 5, 5, 0, 0, 0, 0, 1, 0); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref lookat); GL.Rotate(angle, 0.0f, 1.0f, 0.0f); angle += 0.5f; GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); DrawCube(); glControl.SwapBuffers(); } #endregion #region private void DrawCube() private void DrawCube() { GL.Begin(BeginMode.Quads); GL.Color3(Color.Silver); GL.Vertex3(-1.0f, -1.0f, -1.0f); GL.Vertex3(-1.0f, 1.0f, -1.0f); GL.Vertex3(1.0f, 1.0f, -1.0f); GL.Vertex3(1.0f, -1.0f, -1.0f); GL.Color3(Color.Honeydew); GL.Vertex3(-1.0f, -1.0f, -1.0f); GL.Vertex3(1.0f, -1.0f, -1.0f); GL.Vertex3(1.0f, -1.0f, 1.0f); GL.Vertex3(-1.0f, -1.0f, 1.0f); GL.Color3(Color.Moccasin); GL.Vertex3(-1.0f, -1.0f, -1.0f); GL.Vertex3(-1.0f, -1.0f, 1.0f); GL.Vertex3(-1.0f, 1.0f, 1.0f); GL.Vertex3(-1.0f, 1.0f, -1.0f); GL.Color3(Color.IndianRed); GL.Vertex3(-1.0f, -1.0f, 1.0f); GL.Vertex3(1.0f, -1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 1.0f); GL.Vertex3(-1.0f, 1.0f, 1.0f); GL.Color3(Color.PaleVioletRed); GL.Vertex3(-1.0f, 1.0f, -1.0f); GL.Vertex3(-1.0f, 1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, -1.0f); GL.Color3(Color.ForestGreen); GL.Vertex3(1.0f, -1.0f, -1.0f); GL.Vertex3(1.0f, 1.0f, -1.0f); GL.Vertex3(1.0f, 1.0f, 1.0f); GL.Vertex3(1.0f, -1.0f, 1.0f); GL.End(); } #endregion #region private void GrabScreenshot() Bitmap GrabScreenshot() { Bitmap bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); System.Drawing.Imaging.BitmapData data = bmp.LockBits(this.ClientRectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); GL.ReadPixels(0, 0, this.ClientSize.Width, this.ClientSize.Height, PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0); bmp.UnlockBits(data); bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); return bmp; } #endregion #region public static void Main() /// /// Entry point of this example. /// [STAThread] public static void Main() { using (GameLoopForm example = new GameLoopForm()) { // Get the title and category of this example using reflection. ExampleAttribute info = ((ExampleAttribute)example.GetType().GetCustomAttributes(false)[0]); example.Text = String.Format("OpenTK | {0} {1}: {2}", info.Category, info.Difficulty, info.Title); example.ShowDialog(); } } #endregion } }