diff --git a/Source/Examples/Shapes/Cube.cs b/Source/Examples/Shapes/Cube.cs new file mode 100644 index 00000000..c63b5700 --- /dev/null +++ b/Source/Examples/Shapes/Cube.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenTK.Math; +using System.Drawing; + +namespace Examples.Shapes +{ + public static class Cube + { + public static readonly Vector3[] Vertices = new Vector3[8] + { + new Vector3(-1.0f, -1.0f, 1.0f), + new Vector3( 1.0f, -1.0f, 1.0f), + new Vector3( 1.0f, 1.0f, 1.0f), + new Vector3(-1.0f, 1.0f, 1.0f), + new Vector3(-1.0f, -1.0f, -1.0f), + new Vector3( 1.0f, -1.0f, -1.0f), + new Vector3( 1.0f, 1.0f, -1.0f), + new Vector3(-1.0f, 1.0f, -1.0f), + }; + + public static readonly ushort[] Indices = + { + // front face + 0, 1, 2, 2, 3, 0, + // top face + 3, 2, 6, 6, 7, 3, + // back face + 7, 6, 5, 5, 4, 7, + // left face + 4, 0, 3, 3, 7, 4, + // bottom face + 0, 1, 5, 5, 4, 0, + // right face + 1, 5, 6, 6, 2, 1, + }; + + public static readonly Vector3[] Normals = + { + new Vector3( 1.0f, 0.0f, 0.0f), + new Vector3( 0.0f, 1.0f, 0.0f), + new Vector3( 0.0f, 0.0f, 1.0f), + new Vector3(-1.0f, 0.0f, 0.0f), + new Vector3( 0.0f, -1.0f, 0.0f), + new Vector3( 0.0f, 0.0f, -1.0f), + }; + + public static readonly int[] Colors = + { + Color.Firebrick.ToArgb(), + Color.Honeydew.ToArgb(), + Color.Moccasin.ToArgb(), + Color.Yellow.ToArgb(), + Color.Crimson.ToArgb(), + Color.DarkGoldenrod.ToArgb(), + Color.ForestGreen.ToArgb(), + Color.Sienna.ToArgb(), + }; + } +} diff --git a/Source/Examples/Tutorial/T01_Simple_Window.cs b/Source/Examples/Tutorial/T01_Simple_Window.cs index a06990c0..43499f4d 100644 --- a/Source/Examples/Tutorial/T01_Simple_Window.cs +++ b/Source/Examples/Tutorial/T01_Simple_Window.cs @@ -22,6 +22,8 @@ namespace Examples.Tutorial this.CreateWindow(new DisplayMode(800, 600)); } + #region OnResize + /// /// Override the OnResize method to respond to window resize events. /// Do not forget to call base.OnResize() so that event listeners @@ -39,6 +41,10 @@ namespace Examples.Tutorial base.OnResize(e); } + #endregion + + #region OnRenderFrame + /// /// Override the OnRenderFrame method to add your drawing code. /// Do not forget to call base.OnRenderFrame() so that event listeners @@ -65,6 +71,8 @@ namespace Examples.Tutorial base.OnRenderFrame(e); } + #endregion + #region IExample Members public void Launch() diff --git a/Source/Examples/Tutorial/T02_Resizable_Window.cs b/Source/Examples/Tutorial/T02_Resizable_Window.cs deleted file mode 100644 index d49e1a08..00000000 --- a/Source/Examples/Tutorial/T02_Resizable_Window.cs +++ /dev/null @@ -1,76 +0,0 @@ -#region --- License --- -/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos - * See license.txt for license info - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Drawing; - -using OpenTK; -using OpenTK.OpenGL; - -namespace Examples.Tutorial -{ - class T02_Resizable_Window : GameWindow, IExample - { - public T02_Resizable_Window() - { - this.CreateWindow(new DisplayMode(800, 600)); - } - - /// - /// Override the OnResize method to respond to window resize events. - /// Do not forget to call base.OnResize() so that event listeners - /// will be notified of window resize events! - /// - /// - protected override void OnResize(OpenTK.Platform.ResizeEventArgs e) - { - GL.Viewport(0, 0, e.Width, e.Height); - - GL.MatrixMode(GL.Enums.MatrixMode.PROJECTION); - GL.LoadIdentity(); - GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 4.0); - - base.OnResize(e); - } - - /// - /// Override the OnRenderFrame method to add your drawing code. - /// Do not forget to call base.OnRenderFrame() so that event listeners - /// will be notified of frame rendering events! - /// - /// Not used. - public override void OnRenderFrame(EventArgs e) - { - GL.Clear(GL.Enums.ClearBufferMask.COLOR_BUFFER_BIT); - - GL.Begin(GL.Enums.BeginMode.TRIANGLES); - - GL.Color3(Color.SpringGreen); - GL.Vertex2(-1.0f, 1.0f); - GL.Color3(Color.SteelBlue); - GL.Vertex2(0.0f, -1.0f); - GL.Color3(Color.PeachPuff); - GL.Vertex2(1.0f, 1.0f); - - GL.End(); - - Context.SwapBuffers(); - - base.OnRenderFrame(e); - } - - #region IExample Members - - public void Launch() - { - this.Run(); - } - - #endregion - } -} diff --git a/Source/Examples/Tutorial/T02_Vertex_Array_Cube.cs b/Source/Examples/Tutorial/T02_Vertex_Array_Cube.cs new file mode 100644 index 00000000..b597ea26 --- /dev/null +++ b/Source/Examples/Tutorial/T02_Vertex_Array_Cube.cs @@ -0,0 +1,150 @@ +#region --- License --- +/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos + * See license.txt for license info + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Threading; + +using OpenTK; +using OpenTK.OpenGL; + +namespace Examples.Tutorial +{ + class T02_Vertex_Array_Cube : GameWindow, IExample + { + float angle; + + #region Constructor + + public T02_Vertex_Array_Cube() + { + this.CreateWindow(new DisplayMode(800, 600)); + } + + #endregion + + #region OnLoad + + public override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + GL.ClearColor(Color.MidnightBlue); + GL.Enable(GL.Enums.EnableCap.DEPTH_TEST); + + GL.EnableClientState(GL.Enums.EnableCap.VERTEX_ARRAY); + GL.EnableClientState(GL.Enums.EnableCap.COLOR_ARRAY); + GL.VertexPointer(3, GL.Enums.VertexPointerType.FLOAT, 0, Shapes.Cube.Vertices); + GL.ColorPointer(4, GL.Enums.ColorPointerType.UNSIGNED_BYTE, 0, Shapes.Cube.Colors); + } + + #endregion + + #region OnResize + + /// + /// Called when the user resizes the window. + /// + /// Contains the new width/height of the window. + /// + /// You want the OpenGL viewport to match the window. This is the place to do it! + /// + protected override void OnResize(OpenTK.Platform.ResizeEventArgs e) + { + base.OnResize(e); + + GL.Viewport(0, 0, Width, Height); + + double ratio = e.Width / (double)e.Height; + + GL.MatrixMode(GL.Enums.MatrixMode.PROJECTION); + GL.LoadIdentity(); + Glu.Perspective(45.0, ratio, 1.0, 64.0); + } + + #endregion + + #region OnUpdateFrame + + /// + /// Prepares the next frame for rendering. + /// + /// + /// Place your control logic here. This is the place to respond to user input, + /// update object positions etc. + /// + public override void OnUpdateFrame(UpdateFrameEventArgs e) + { + if (Keyboard[0][OpenTK.Input.Key.Escape]) + { + this.Exit(); + return; + } + + if ((Keyboard[0][OpenTK.Input.Key.AltLeft] || Keyboard[0][OpenTK.Input.Key.AltRight]) && + Keyboard[0][OpenTK.Input.Key.Enter]) + { + Fullscreen = !Fullscreen; + } + + GL.MatrixMode(GL.Enums.MatrixMode.MODELVIEW); + GL.LoadIdentity(); + Glu.LookAt( + 0.0, 5.0, 5.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0 + ); + + GL.Rotate(angle, 0.0f, 1.0f, 0.0f); + angle += 180.0f * e.Time; + if (angle > 720.0f) + angle -= 720.0f; + } + + #endregion + + #region OnRenderFrame + + /// + /// Place your rendering code here. + /// + public override void OnRenderFrame(EventArgs e) + { + GL.Clear(GL.Enums.ClearBufferMask.COLOR_BUFFER_BIT | GL.Enums.ClearBufferMask.DEPTH_BUFFER_BIT); + + unsafe + { + fixed (ushort* index_pointer = Shapes.Cube.Indices) + { + GL.DrawElements(GL.Enums.BeginMode.TRIANGLES, Shapes.Cube.Indices.Length, + GL.Enums.All.UNSIGNED_SHORT, index_pointer); + } + } + + Context.SwapBuffers(); + Thread.Sleep(0); + } + + #endregion + + #region public void Launch() + + /// + /// Launches this example. + /// + /// + /// Provides a simple way for the example launcher to launch the examples. + /// + public void Launch() + { + Run(); + } + + #endregion + } +} diff --git a/Source/Examples/Tutorial/T03_Immediate_Mode_Cube.cs b/Source/Examples/Tutorial/T03_Immediate_Mode_Cube.cs index f2e28135..35b96d9c 100644 --- a/Source/Examples/Tutorial/T03_Immediate_Mode_Cube.cs +++ b/Source/Examples/Tutorial/T03_Immediate_Mode_Cube.cs @@ -46,7 +46,7 @@ namespace Examples.Tutorial { base.OnLoad(e); - GL.ClearColor(0.1f, 0.1f, 0.5f, 0.0f); + GL.ClearColor(Color.MidnightBlue); GL.Enable(GL.Enums.EnableCap.DEPTH_TEST); } @@ -85,7 +85,7 @@ namespace Examples.Tutorial /// Place your control logic here. This is the place to respond to user input, /// update object positions etc. /// - public override void OnUpdateFrame(EventArgs e) + public override void OnUpdateFrame(UpdateFrameEventArgs e) { if (Keyboard[0][OpenTK.Input.Key.Escape]) { diff --git a/Source/Examples/Tutorial/T07_Display_Lists_Flower.cs b/Source/Examples/Tutorial/T07_Display_Lists_Flower.cs index f959efd6..6e53104c 100644 --- a/Source/Examples/Tutorial/T07_Display_Lists_Flower.cs +++ b/Source/Examples/Tutorial/T07_Display_Lists_Flower.cs @@ -123,7 +123,7 @@ namespace Examples.Tutorial #region OnUpdateFrame - public override void OnUpdateFrame(EventArgs e) + public override void OnUpdateFrame(UpdateFrameEventArgs e) { base.OnUpdateFrame(e); diff --git a/Source/Examples/Tutorial/T08_VBO.cs b/Source/Examples/Tutorial/T08_VBO.cs index 662456a2..956acbf4 100644 --- a/Source/Examples/Tutorial/T08_VBO.cs +++ b/Source/Examples/Tutorial/T08_VBO.cs @@ -129,7 +129,7 @@ namespace Examples.Tutorial /// Place your control logic here. This is the place to respond to user input, /// update object positions etc. /// - public override void OnUpdateFrame(EventArgs e) + public override void OnUpdateFrame(UpdateFrameEventArgs e) { if (Keyboard[0][OpenTK.Input.Key.Escape]) { diff --git a/Source/Examples/Tutorial/T10_GLSL_Cube.cs b/Source/Examples/Tutorial/T10_GLSL_Cube.cs index 4a735964..a933b3c5 100644 --- a/Source/Examples/Tutorial/T10_GLSL_Cube.cs +++ b/Source/Examples/Tutorial/T10_GLSL_Cube.cs @@ -148,7 +148,7 @@ namespace Examples.Tutorial /// Occurs when it is time to update the next frame. /// /// Not used yet. - public override void OnUpdateFrame(EventArgs e) + public override void OnUpdateFrame(UpdateFrameEventArgs e) { base.OnUpdateFrame(e); diff --git a/Source/Examples/WinForms/W03_Extensions.resx b/Source/Examples/WinForms/W03_Extensions.resx new file mode 100644 index 00000000..7aafc39c --- /dev/null +++ b/Source/Examples/WinForms/W03_Extensions.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/Source/OpenTK/GLControl.resx b/Source/OpenTK/GLControl.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/Source/OpenTK/GLControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Source/OpenTK/GameWindow.cs b/Source/OpenTK/GameWindow.cs index 96a83a6f..88fc3c27 100644 --- a/Source/OpenTK/GameWindow.cs +++ b/Source/OpenTK/GameWindow.cs @@ -316,12 +316,19 @@ namespace OpenTK Debug.Print("Entering main loop"); + System.Diagnostics.Stopwatch watch = new Stopwatch(); + watch.Reset(); + UpdateFrameEventArgs updateArgs = new UpdateFrameEventArgs(); + while (this.Exists && !IsExiting) { this.ProcessEvents(); if (!IsExiting) { - this.OnUpdateFrame(EventArgs.Empty); + updateArgs.Time = watch.ElapsedMilliseconds / 1000.0f; + watch.Reset(); + watch.Start(); + this.OnUpdateFrame(updateArgs); this.OnRenderFrame(EventArgs.Empty); } } @@ -388,7 +395,7 @@ namespace OpenTK #endregion - #region public virtual void OnUpdateFrame(EventArgs e) + #region public virtual void OnUpdateFrame(UpdateFrameEventArgs e) /// /// Raises the UpdateFrame event. Override in derived classes to update a frame. @@ -397,7 +404,7 @@ namespace OpenTK /// If overriden, the base.OnUpdateFrame() function should be called, to ensure /// listeners are notified of UpdateFrame events. /// - public virtual void OnUpdateFrame(EventArgs e) + public virtual void OnUpdateFrame(UpdateFrameEventArgs e) { if (!this.Exists && !this.IsExiting) { @@ -616,4 +623,18 @@ namespace OpenTK #endregion } + + public class UpdateFrameEventArgs : EventArgs + { + private float time; + + /// + /// Gets the Time elapsed between frame updates, in seconds. + /// + public float Time + { + get { return time; } + internal set { time = value; } + } + } } diff --git a/Source/OpenTK/Platform/IGameWindow.cs b/Source/OpenTK/Platform/IGameWindow.cs index b7166a8e..3b52f0d4 100644 --- a/Source/OpenTK/Platform/IGameWindow.cs +++ b/Source/OpenTK/Platform/IGameWindow.cs @@ -15,7 +15,7 @@ namespace OpenTK.Platform void Run(); void OnRenderFrame(EventArgs e); - void OnUpdateFrame(EventArgs e); + void OnUpdateFrame(UpdateFrameEventArgs e); void OnLoad(EventArgs e); void Exit(); @@ -27,7 +27,7 @@ namespace OpenTK.Platform IList Keyboard { get; } } - public delegate void UpdateFrameEvent(object sender, EventArgs e); + public delegate void UpdateFrameEvent(object sender, UpdateFrameEventArgs e); public delegate void RenderFrameEvent(object sender, EventArgs e); public delegate void LoadEvent(object sender, EventArgs e); }