Added timing information to UpdateFrame.

Removed T02_Resizable_Window.cs and added T02_Vertex_Array_Cube.cs
Added Shapes/Cube.cs to Examples.
This commit is contained in:
the_fiddler 2007-09-22 22:01:43 +00:00
parent 7bf2e84373
commit bb2b3f8eae
12 changed files with 494 additions and 86 deletions

View file

@ -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(),
};
}
}

View file

@ -22,6 +22,8 @@ namespace Examples.Tutorial
this.CreateWindow(new DisplayMode(800, 600));
}
#region OnResize
/// <summary>
/// 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
/// <summary>
/// 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()

View file

@ -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));
}
/// <summary>
/// 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!
/// </summary>
/// <param name="e"></param>
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);
}
/// <summary>
/// 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!
/// </summary>
/// <param name="e">Not used.</param>
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
}
}

View file

@ -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
/// <summary>
/// Called when the user resizes the window.
/// </summary>
/// <param name="e">Contains the new width/height of the window.</param>
/// <remarks>
/// You want the OpenGL viewport to match the window. This is the place to do it!
/// </remarks>
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
/// <summary>
/// Prepares the next frame for rendering.
/// </summary>
/// <remarks>
/// Place your control logic here. This is the place to respond to user input,
/// update object positions etc.
/// </remarks>
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
/// <summary>
/// Place your rendering code here.
/// </summary>
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()
/// <summary>
/// Launches this example.
/// </summary>
/// <remarks>
/// Provides a simple way for the example launcher to launch the examples.
/// </remarks>
public void Launch()
{
Run();
}
#endregion
}
}

View file

@ -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.
/// </remarks>
public override void OnUpdateFrame(EventArgs e)
public override void OnUpdateFrame(UpdateFrameEventArgs e)
{
if (Keyboard[0][OpenTK.Input.Key.Escape])
{

View file

@ -123,7 +123,7 @@ namespace Examples.Tutorial
#region OnUpdateFrame
public override void OnUpdateFrame(EventArgs e)
public override void OnUpdateFrame(UpdateFrameEventArgs e)
{
base.OnUpdateFrame(e);

View file

@ -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.
/// </remarks>
public override void OnUpdateFrame(EventArgs e)
public override void OnUpdateFrame(UpdateFrameEventArgs e)
{
if (Keyboard[0][OpenTK.Input.Key.Escape])
{

View file

@ -148,7 +148,7 @@ namespace Examples.Tutorial
/// Occurs when it is time to update the next frame.
/// </summary>
/// <param name="e">Not used yet.</param>
public override void OnUpdateFrame(EventArgs e)
public override void OnUpdateFrame(UpdateFrameEventArgs e)
{
base.OnUpdateFrame(e);

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="backgroundWorker1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -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)
/// <summary>
/// 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.
/// </remarks>
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;
/// <summary>
/// Gets the Time elapsed between frame updates, in seconds.
/// </summary>
public float Time
{
get { return time; }
internal set { time = value; }
}
}
}

View file

@ -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<OpenTK.Input.Keyboard> 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);
}