Backported bugfixes from 1.0 branch.

This commit is contained in:
the_fiddler 2010-02-03 19:04:42 +00:00
parent ea5b4f9f06
commit da7e4c7252
39 changed files with 513 additions and 550 deletions

View file

@ -7582,6 +7582,10 @@ ActiveUniformBlockParameter enum:
use ARB_uniform_buffer_object UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
use ARB_uniform_buffer_object UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER
use ARB_uniform_buffer_object UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER
# Used in primitive restart
EnableCap enum:
PRIMITIVE_RESTART = 0x8F9D # 3.1 (different from NV_primitive_restart)
# Non-core

View file

@ -116,8 +116,7 @@ namespace Examples.Tutorial
return;
}
// Alt+Enter toggles fullscreen mode.
if ((Keyboard[Key.AltLeft] || Keyboard[Key.AltRight]) && Keyboard[Key.Enter])
if (Keyboard[Key.F11])
if (WindowState != WindowState.Fullscreen)
WindowState = WindowState.Fullscreen;
else

View file

@ -108,8 +108,7 @@ namespace Examples.Tutorial
return;
}
if ((Keyboard[OpenTK.Input.Key.AltLeft] || Keyboard[OpenTK.Input.Key.AltRight]) &&
Keyboard[OpenTK.Input.Key.Enter])
if (Keyboard[OpenTK.Input.Key.F11])
if (WindowState != WindowState.Fullscreen)
WindowState = WindowState.Fullscreen;
else

View file

@ -221,8 +221,7 @@ namespace Examples.Tutorial
if (Keyboard[OpenTK.Input.Key.Escape])
this.Exit();
if ((Keyboard[OpenTK.Input.Key.AltLeft] || Keyboard[OpenTK.Input.Key.AltRight]) &&
Keyboard[OpenTK.Input.Key.Enter])
if (Keyboard[OpenTK.Input.Key.F11])
if (WindowState != WindowState.Fullscreen)
WindowState = WindowState.Fullscreen;
else

View file

@ -66,14 +66,14 @@ namespace Examples.Tutorial
{
base.OnLoad(e);
Color color = Color.MidnightBlue;
Color4 color = Color4.MidnightBlue;
GL.ClearColor(color.R, color.G, color.B, color.A);
GL.Enable((All)EnableCap.DepthTest);
}
#endregion
#region OnResize
#region OnResize
/// <summary>
/// Called when the user resizes the window.
@ -95,7 +95,7 @@ namespace Examples.Tutorial
#endregion
#region OnUpdateFrame
#region OnUpdateFrame
/// <summary>
/// Prepares the next frame for rendering.
@ -115,7 +115,7 @@ namespace Examples.Tutorial
#endregion
#region OnRenderFrame
#region OnRenderFrame
/// <summary>
/// Place your rendering code here.
@ -138,7 +138,7 @@ namespace Examples.Tutorial
#endregion
#region private void DrawCube()
#region private void DrawCube()
private void DrawCube()
{
@ -188,7 +188,7 @@ namespace Examples.Tutorial
#endregion
#region public static void Main()
#region public static void Main()
/// <summary>
/// Entry point of this example.

View file

@ -41,7 +41,7 @@ using OpenTK.Graphics.ES20;
namespace Examples.Tutorial
{
[Example("Immediate mode", ExampleCategory.OpenGLES, "2.0", Documentation = "SimpleES20Window")]
[Example("Simple ES 2.0", ExampleCategory.OpenGLES, "2.0", Documentation = "SimpleES20Window")]
public class SimpleES20Window : GameWindow
{
#region Constructor
@ -58,7 +58,7 @@ namespace Examples.Tutorial
{
base.OnLoad(e);
Color color = Color.MidnightBlue;
Color4 color = Color4.MidnightBlue;
GL.ClearColor(color.R, color.G, color.B, color.A);
GL.Enable(EnableCap.DepthTest);
}
@ -119,48 +119,6 @@ namespace Examples.Tutorial
private void DrawCube()
{
#if false
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();
#endif
}
#endregion

View file

@ -43,17 +43,7 @@ namespace Examples
public FullscreenAntialias()
: base(800, 600, new GraphicsMode(32, 0, 0, 4))
{
Keyboard.KeyDown += delegate(object sender, KeyboardKeyEventArgs e)
{
if (e.Key == Key.Escape)
this.Exit();
if ((e.Key == Key.AltLeft || e.Key == Key.AltRight) && (e.Key == Key.Enter || e.Key == Key.KeypadEnter))
if (this.WindowState == WindowState.Fullscreen)
this.WindowState = WindowState.Normal;
else
this.WindowState = WindowState.Fullscreen;
};
Keyboard.KeyDown += Keyboard_KeyDown;
}
#region Keyboard_KeyDown
@ -63,12 +53,12 @@ namespace Examples
/// </summary>
/// <param name="sender">The KeyboardDevice which generated this event.</param>
/// <param name="key">The key that was pressed.</param>
void Keyboard_KeyDown(KeyboardDevice sender, Key key)
void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e)
{
if (sender[Key.Escape])
if (e.Key == Key.Escape)
this.Exit();
if ((sender[Key.AltLeft] || sender[Key.AltRight]) && (sender[Key.Enter] || sender[Key.KeypadEnter]))
if (e.Key == Key.F11)
if (this.WindowState == WindowState.Fullscreen)
this.WindowState = WindowState.Normal;
else

View file

@ -39,7 +39,7 @@ namespace Examples.Tutorial
if (e.Key == Key.Escape)
this.Exit();
if ((e.Key == Key.AltLeft || e.Key == Key.AltRight) && (e.Key == Key.Enter || e.Key == Key.KeypadEnter))
if (e.Key == Key.F11)
if (this.WindowState == WindowState.Fullscreen)
this.WindowState = WindowState.Normal;
else

View file

@ -64,7 +64,7 @@ namespace Examples.Tests
Utilities.SetWindowTitle(game);
game.Keyboard.KeyUp += delegate(object sender, OpenTK.Input.KeyboardKeyEventArgs e)
{
if (e.Key == OpenTK.Input.Key.Space)
if (e.Key == OpenTK.Input.Key.F11)
{
if (game.WindowState == OpenTK.WindowState.Fullscreen)
game.WindowState = OpenTK.WindowState.Normal;

View file

@ -29,6 +29,10 @@ namespace Examples
return (int)((c.A << 24) | (c.B << 16) | (c.G << 8) | c.R);
}
/// <summary>
/// Sets the window title to the name of the sample.
/// </summary>
/// <param name="window"></param>
public static void SetWindowTitle(GameWindow window)
{
ExampleAttribute info = GetExampleAttribute(window.GetType());
@ -36,6 +40,10 @@ namespace Examples
window.Icon = OpenTK.Examples.Properties.Resources.App;
}
/// <summary>
/// Sets the window title to the name of the sample.
/// </summary>
/// <param name="window"></param>
public static void SetWindowTitle(System.Windows.Forms.Form window)
{
ExampleAttribute info = GetExampleAttribute(window.GetType());

View file

@ -59,8 +59,7 @@ namespace OpenTK.Audio
#region static AudioContext()
/// <private />
/// <static />
/// \internal
/// <summary>
/// Runs before the actual class constructor, to load available devices.
/// </summary>
@ -224,7 +223,7 @@ namespace OpenTK.Audio
Four = 4,
}
/// <private />
/// \internal
/// <summary>Creates the audio context using the specified device.</summary>
/// <param name="device">The device descriptor obtained through AudioContext.AvailableDevices, or null for the default device.</param>
/// <param name="freq">Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default.</param>
@ -358,7 +357,7 @@ namespace OpenTK.Audio
#region static void MakeCurrent(AudioContext context)
/// <private />
/// \internal
/// <summary>Makes the specified AudioContext current in the calling thread.</summary>
/// <param name="context">The OpenTK.Audio.AudioContext to make current, or null.</param>
/// <exception cref="ObjectDisposedException">

View file

@ -294,9 +294,9 @@ namespace OpenTK.Audio.OpenAL
/// <summary>This function retrieves a set of three floating-point values from a property of the listener.</summary>
/// <param name="param">The name of the attribute to be retrieved: ALListener3f.Position, ALListener3f.Velocity</param>
/// <param name="value1">Pointers to the three floating-point being retrieved.</param>
/// <param name="value2">Pointers to the three floating-point being retrieved.</param>
/// <param name="value3">Pointers to the three floating-point being retrieved.</param>
/// <param name="value1">The first floating-point value being retrieved.</param>
/// <param name="value2">The second floating-point value being retrieved.</param>
/// <param name="value3">The third floating-point value being retrieved.</param>
[DllImport(AL.Lib, EntryPoint = "alGetListener3f", ExactSpelling = true, CallingConvention = AL.Style), SuppressUnmanagedCodeSecurity()]
public static extern void GetListener(ALListener3f param, [Out] out float value1, [Out] out float value2, [Out] out float value3);
// AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );

View file

@ -285,6 +285,27 @@ namespace OpenTK
Context.MakeCurrent(WindowInfo);
}
#endregion
#region OnClose
/// <summary>
/// Called when the NativeWindow is about to close.
/// </summary>
/// <param name="e">
/// The <see cref="System.ComponentModel.CancelEventArgs" /> for this event.
/// Set e.Cancel to true in order to stop the GameWindow from closing.</param>
protected override void OnClosing (System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
if (!e.Cancel)
{
isExiting = true;
OnUnloadInternal(EventArgs.Empty);
}
}
#endregion
#region OnLoad
@ -381,20 +402,25 @@ namespace OpenTK
Debug.Print("Entering main loop.");
update_watch.Start();
render_watch.Start();
while (!IsExiting && Exists)
while (true)
{
ProcessEvents();
DispatchUpdateAndRenderFrame(this, EventArgs.Empty);
if (Exists && !IsExiting)
DispatchUpdateAndRenderFrame(this, EventArgs.Empty);
else
return;
}
}
finally
{
OnUnloadInternal(EventArgs.Empty);
Move -= DispatchUpdateAndRenderFrame;
Resize -= DispatchUpdateAndRenderFrame;
if (Exists)
{
Dispose();
//while (this.Exists) ProcessEvents(); // TODO: Should similar behaviour be retained, possibly on native window level?
// TODO: Should similar behaviour be retained, possibly on native window level?
//while (this.Exists)
// ProcessEvents(false);
}
}
}
@ -464,16 +490,6 @@ namespace OpenTK
return;
double time_left = next_render - time;
// Todo: remove this?
if (VSync == VSyncMode.Adaptive)
{
// Check if we have enough time for a vsync
if (TargetRenderPeriod != 0 && RenderTime > 2.0 * TargetRenderPeriod)
Context.VSync = false;
else
Context.VSync = true;
}
if (time_left <= 0.0)
{
// Schedule next render event. The 1 second cap ensures
@ -487,6 +503,22 @@ namespace OpenTK
if (time > 0)
{
// Todo: revisit this code. Maybe check average framerate instead?
// Note: VSyncMode.Adaptive enables vsync by default. The code below
// is supposed to disable vsync if framerate becomes too low (half of target
// framerate in the current approach) and reenable once the framerate
// rises again.
// Note 2: calling Context.VSync = true repeatedly seems to cause jitter on
// some configurations. If possible, we should avoid repeated calls.
if (VSync == VSyncMode.Adaptive && TargetRenderPeriod != 0)
{
// Check if we have enough time for a vsync
if (RenderTime > 2.0 * TargetRenderPeriod)
Context.VSync = false;
else
Context.VSync = true;
}
render_period = render_args.Time = time;
OnRenderFrameInternal(render_args);
render_time = render_watch.Elapsed.TotalSeconds;
@ -864,11 +896,33 @@ namespace OpenTK
#endregion
#endregion
#region WindowState
#region Events
/// <summary>
/// Gets or states the state of the NativeWindow.
/// </summary>
public override WindowState WindowState
{
get
{
return base.WindowState;
}
set
{
base.WindowState = value;
Debug.Print("Updating Context after setting WindowState to {0}", value);
/// <summary>
if (Context != null)
Context.Update(WindowInfo);
}
}
#endregion
#endregion
#region Events
/// <summary>
/// Occurs before the window is displayed for the first time.
/// </summary>
public event EventHandler<EventArgs> Load;
@ -1018,7 +1072,8 @@ namespace OpenTK
/// </summary>
On,
/// <summary>
/// VSync enabled, but automatically disabled if framerate falls below a specified limit.
/// VSync enabled, unless framerate falls below one half of target framerate.
/// If no target framerate is specified, this behaves exactly like <see cref="VSyncMode.On"/>.
/// </summary>
Adaptive,
}

View file

@ -115,10 +115,10 @@ namespace OpenTK.Graphics
public int ToArgb()
{
uint value =
(uint)(A / Byte.MaxValue) << 24 |
(uint)(R / Byte.MaxValue) << 16 |
(uint)(G / Byte.MaxValue) << 8 |
(uint)(B / Byte.MaxValue);
(uint)(A * Byte.MaxValue) << 24 |
(uint)(R * Byte.MaxValue) << 16 |
(uint)(G * Byte.MaxValue) << 8 |
(uint)(B * Byte.MaxValue);
return unchecked((int)value);
}

View file

@ -40,11 +40,6 @@ namespace OpenTK.Graphics
#region --- Constructors ---
static GraphicsContext()
{
GetCurrentContext = Factory.Default.CreateGetCurrentGraphicsContext();
}
// Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method).
GraphicsContext(ContextHandle handle)
{
@ -105,14 +100,25 @@ namespace OpenTK.Graphics
// Todo: Add a DummyFactory implementing IPlatformFactory.
if (designMode)
{
implementation = new Platform.Dummy.DummyGLContext();
}
else
{
IPlatformFactory factory = null;
switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded)
{
case false: implementation = Factory.Default.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break;
case true: implementation = Factory.Embedded.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break;
case false: factory = Factory.Default; break;
case true: factory = Factory.Embedded; break;
}
implementation = factory.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags);
// Note: this approach does not allow us to mix native and EGL contexts in the same process.
// This should not be a problem, as this use-case is not interesting for regular applications.
if (GetCurrentContext == null)
GetCurrentContext = factory.CreateGetCurrentGraphicsContext();
}
available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
}
finally
@ -252,6 +258,10 @@ namespace OpenTK.Graphics
/// <summary>
/// Gets the GraphicsContext that is current in the calling thread.
/// </summary>
/// <remarks>
/// Note: this property will not function correctly when both desktop and EGL contexts are
/// available in the same process. This scenario is very unlikely to appear in practice.
/// </remarks>
public static IGraphicsContext CurrentContext
{
get

View file

@ -5756,6 +5756,7 @@ namespace OpenTK.Graphics.OpenGL
RasterizerDiscard = ((int)0x8C89),
FramebufferSrgb = ((int)0x8DB9),
SampleMask = ((int)0x8E51),
PrimitiveRestart = ((int)0x8F9D),
}
public enum ErrorCode : int

View file

@ -729,7 +729,7 @@ namespace OpenTK.Graphics.OpenGL
public static void TexCoordPointer(int size, TexCoordPointerType type, int stride, int offset)
{
TexCoordPointer(size, type, stride, offset);
TexCoordPointer(size, type, stride, (IntPtr)offset);
}
public static void VertexAttribPointer(int index, int size, VertexAttribPointerType type, bool normalized, int stride, int offset)

View file

@ -136,7 +136,7 @@ namespace OpenTK.Input
/// </summary>
public int Wheel
{
get { return (int)(wheel + 0.5f); }
get { return (int)Math.Round(wheel, MidpointRounding.AwayFromZero); }
internal set { WheelPrecise = value; }
}
@ -306,7 +306,7 @@ namespace OpenTK.Input
{
get
{
int result = (int)(wheel - wheel_last_accessed + 0.5f);
int result = (int)Math.Round(wheel - wheel_last_accessed, MidpointRounding.AwayFromZero);
wheel_last_accessed = (int)wheel;
return result;
}
@ -614,13 +614,13 @@ namespace OpenTK.Input
/// Gets the value of the wheel in integer units.
/// To support high-precision mice, it is recommended to use <see cref="ValuePrecise"/> instead.
/// </summary>
public int Value { get { return (int)(value + 0.5f); } }
public int Value { get { return (int)Math.Round(value, MidpointRounding.AwayFromZero); } }
/// <summary>
/// Gets the change in value of the wheel for this event in integer units.
/// To support high-precision mice, it is recommended to use <see cref="DeltaPrecise"/> instead.
/// </summary>
public int Delta { get { return (int)(delta + 0.5f); } }
public int Delta { get { return (int)Math.Round(delta, MidpointRounding.AwayFromZero); } }
/// <summary>
/// Gets the precise value of the wheel in floating-point units.

View file

@ -167,7 +167,7 @@ namespace OpenTK
{
get
{
return (float)System.Math.Sqrt(X * X + Y * Y);
return System.Math.Sqrt(X * X + Y * Y);
}
}
@ -230,7 +230,7 @@ namespace OpenTK
/// </summary>
public void Normalize()
{
double scale = 1.0f / Length;
double scale = 1.0 / Length;
X *= scale;
Y *= scale;
}
@ -627,7 +627,7 @@ namespace OpenTK
/// <returns>The normalized vector</returns>
public static Vector2d Normalize(Vector2d vec)
{
double scale = 1.0f / vec.Length;
double scale = 1.0 / vec.Length;
vec.X *= scale;
vec.Y *= scale;
return vec;
@ -640,7 +640,7 @@ namespace OpenTK
/// <param name="result">The normalized vector</param>
public static void Normalize(ref Vector2d vec, out Vector2d result)
{
double scale = 1.0f / vec.Length;
double scale = 1.0 / vec.Length;
result.X = vec.X * scale;
result.Y = vec.Y * scale;
}
@ -882,7 +882,7 @@ namespace OpenTK
/// <returns>The result of the operation.</returns>
public static Vector2d operator /(Vector2d vec, double f)
{
double mult = 1.0f / f;
double mult = 1.0 / f;
vec.X *= mult;
vec.Y *= mult;
return vec;

View file

@ -199,7 +199,7 @@ namespace OpenTK
{
get
{
return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z);
return System.Math.Sqrt(X * X + Y * Y + Z * Z);
}
}
@ -220,7 +220,7 @@ namespace OpenTK
{
get
{
return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z);
return 1.0 / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z);
}
}
@ -254,7 +254,7 @@ namespace OpenTK
/// </summary>
public void Normalize()
{
double scale = 1.0f / this.Length;
double scale = 1.0 / this.Length;
X *= scale;
Y *= scale;
Z *= scale;
@ -433,7 +433,7 @@ namespace OpenTK
[Obsolete("Use static Divide() method instead.")]
public static Vector3d Div(Vector3d a, double f)
{
double mult = 1.0f / f;
double mult = 1.0 / f;
a.X *= mult;
a.Y *= mult;
a.Z *= mult;
@ -449,7 +449,7 @@ namespace OpenTK
[Obsolete("Use static Divide() method instead.")]
public static void Div(ref Vector3d a, double f, out Vector3d result)
{
double mult = 1.0f / f;
double mult = 1.0 / f;
result.X = a.X * mult;
result.Y = a.Y * mult;
result.Z = a.Z * mult;
@ -747,7 +747,7 @@ namespace OpenTK
/// <returns>The normalized vector</returns>
public static Vector3d Normalize(Vector3d vec)
{
double scale = 1.0f / vec.Length;
double scale = 1.0 / vec.Length;
vec.X *= scale;
vec.Y *= scale;
vec.Z *= scale;
@ -761,7 +761,7 @@ namespace OpenTK
/// <param name="result">The normalized vector</param>
public static void Normalize(ref Vector3d vec, out Vector3d result)
{
double scale = 1.0f / vec.Length;
double scale = 1.0 / vec.Length;
result.X = vec.X * scale;
result.Y = vec.Y * scale;
result.Z = vec.Z * scale;
@ -1085,7 +1085,7 @@ namespace OpenTK
/// <param name="result">The transformed vector</param>
public static void Transform(ref Vector3d vec, ref Matrix4d mat, out Vector3d result)
{
Vector4d v4 = new Vector4d(vec.X, vec.Y, vec.Z, 1.0f);
Vector4d v4 = new Vector4d(vec.X, vec.Y, vec.Z, 1.0);
Vector4d.Transform(ref v4, ref mat, out v4);
result = v4.Xyz;
}

View file

@ -260,7 +260,7 @@ namespace OpenTK
{
get
{
return (double)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
return System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
}
}
@ -281,7 +281,7 @@ namespace OpenTK
{
get
{
return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
return 1.0 / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
}
}
@ -314,7 +314,7 @@ namespace OpenTK
/// </summary>
public void Normalize()
{
double scale = 1.0f / this.Length;
double scale = 1.0 / this.Length;
X *= scale;
Y *= scale;
Z *= scale;
@ -469,7 +469,7 @@ namespace OpenTK
[Obsolete("Use static Divide() method instead.")]
public static Vector4d Div(Vector4d a, double f)
{
double mult = 1.0f / f;
double mult = 1.0 / f;
a.X *= mult;
a.Y *= mult;
a.Z *= mult;
@ -486,7 +486,7 @@ namespace OpenTK
[Obsolete("Use static Divide() method instead.")]
public static void Div(ref Vector4d a, double f, out Vector4d result)
{
double mult = 1.0f / f;
double mult = 1.0 / f;
result.X = a.X * mult;
result.Y = a.Y * mult;
result.Z = a.Z * mult;
@ -761,7 +761,7 @@ namespace OpenTK
/// <returns>The normalized vector</returns>
public static Vector4d Normalize(Vector4d vec)
{
double scale = 1.0f / vec.Length;
double scale = 1.0 / vec.Length;
vec.X *= scale;
vec.Y *= scale;
vec.Z *= scale;
@ -776,7 +776,7 @@ namespace OpenTK
/// <param name="result">The normalized vector</param>
public static void Normalize(ref Vector4d vec, out Vector4d result)
{
double scale = 1.0f / vec.Length;
double scale = 1.0 / vec.Length;
result.X = vec.X * scale;
result.Y = vec.Y * scale;
result.Z = vec.Z * scale;

View file

@ -485,7 +485,7 @@ namespace OpenTK
/// <summary>
/// Gets or states the state of the NativeWindow.
/// </summary>
public WindowState WindowState
public virtual WindowState WindowState
{
get
{

View file

@ -7,5 +7,6 @@
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
</configuration>

View file

@ -33,108 +33,13 @@ using OpenTK.Graphics;
namespace OpenTK.Platform.Egl
{
// Note: the Workaround structs declared in each type below work around
// gmcs 2.4.2 bug #530270 (https://bugzilla.novell.com/show_bug.cgi?id=530270).
// They don't cause any change in functionality other than make the compiler happy.
struct EGLNativeDisplayType
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLNativeDisplayType(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
public static readonly EGLNativeDisplayType Default = new EGLNativeDisplayType();
}
struct EGLNativePixmapType
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLNativePixmapType(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
}
struct EGLConfig
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLConfig(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
}
struct EGLContext
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLContext(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
public static readonly EGLContext None;
}
struct EGLDisplay
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLDisplay(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
public static readonly EGLDisplay Null = default(EGLDisplay);
}
struct EGLSurface
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLSurface(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
public static readonly EGLSurface None = default(EGLSurface);
}
struct EGLClientBuffer
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLClientBuffer(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
}
using EGLNativeDisplayType = IntPtr;
using EGLNativePixmapType = IntPtr;
using EGLConfig = IntPtr;
using EGLContext = IntPtr;
using EGLDisplay = IntPtr;
using EGLSurface = IntPtr;
using EGLClientBuffer = IntPtr;
static partial class Egl
{
@ -267,21 +172,14 @@ namespace OpenTK.Platform.Egl
public static extern int GetError();
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetDisplay")]
static extern IntPtr eglGetDisplay(EGLNativeDisplayType display_id);
public static EGLDisplay GetDisplay(EGLNativeDisplayType display_id)
{
IntPtr ptr = eglGetDisplay(display_id);
EGLDisplay ret = new EGLDisplay(ptr);
return ret;
}
public static extern EGLDisplay GetDisplay(EGLNativeDisplayType display_id);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglInitialize")]
[return: MarshalAsAttribute(UnmanagedType.I1)]
//[return: MarshalAsAttribute(UnmanagedType.I1)]
public static extern bool Initialize(EGLDisplay dpy, out int major, out int minor);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglTerminate")]
[return: MarshalAsAttribute(UnmanagedType.I1)]
//[return: MarshalAsAttribute(UnmanagedType.I1)]
public static extern bool Terminate(EGLDisplay dpy);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryString")]
@ -300,14 +198,7 @@ namespace OpenTK.Platform.Egl
public static extern bool GetConfigAttrib(EGLDisplay dpy, EGLConfig config, int attribute, out int value);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreateWindowSurface")]
static extern IntPtr eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, int[] attrib_list);
public static EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, int[] attrib_list)
{
IntPtr ptr = eglCreateWindowSurface(dpy, config, win, attrib_list);
EGLSurface ret = new EGLSurface(ptr);
return ret;
}
public static extern EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, int[] attrib_list);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePbufferSurface")]
public static extern EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list);
@ -363,9 +254,9 @@ namespace OpenTK.Platform.Egl
public static EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list)
{
IntPtr ptr = eglCreateContext(dpy, config, share_context, attrib_list);
if (ptr == EGLContext.None.Handle.Value)
if (ptr == IntPtr.Zero)
throw new GraphicsContextException(String.Format("Failed to create EGL context, error: {0}.", Egl.GetError()));
return new EGLContext(ptr);
return ptr;
}
[DllImportAttribute("libEGL.dll", EntryPoint = "eglDestroyContext")]

View file

@ -38,7 +38,7 @@ namespace OpenTK.Platform.Egl
#region Fields
EglWindowInfo WindowInfo;
EGLContext HandleAsEGLContext { get { return new EGLContext(Handle.Handle); } set { Handle = new ContextHandle(value.Handle.Value); } }
IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } }
bool vsync = true; // Default vsync value is defined as 1 (true) in EGL.
#endregion
@ -64,13 +64,13 @@ namespace OpenTK.Platform.Egl
Mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
if (!Mode.Index.HasValue)
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
EGLConfig config = new EGLConfig(mode.Index.Value);
IntPtr config = Mode.Index.Value;
if (window.Surface.Handle == EGLSurface.None.Handle)
if (window.Surface == IntPtr.Zero)
window.CreateWindowSurface(config);
int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE };
HandleAsEGLContext = Egl.CreateContext(window.Display, config, shared != null ? shared.HandleAsEGLContext : EGLContext.None, attrib_list);
HandleAsEGLContext = Egl.CreateContext(window.Display, config, shared != null ? shared.HandleAsEGLContext : IntPtr.Zero, attrib_list);
MakeCurrent(window);
}
@ -108,7 +108,7 @@ namespace OpenTK.Platform.Egl
public override bool IsCurrent
{
get { return Egl.GetCurrentContext().Handle == HandleAsEGLContext.Handle; }
get { return Egl.GetCurrentContext() == HandleAsEGLContext; }
}
public override bool VSync
@ -155,12 +155,12 @@ namespace OpenTK.Platform.Egl
{
if (manual)
{
Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, EGLContext.None);
Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, IntPtr.Zero);
Egl.DestroyContext(WindowInfo.Display, HandleAsEGLContext);
}
else
{
Debug.Print("[Warning] {0}:{1} was not disposed.", this.GetType().Name, HandleAsEGLContext.Handle);
Debug.Print("[Warning] {0}:{1} was not disposed.", this.GetType().Name, HandleAsEGLContext);
}
IsDisposed = true;
}

View file

@ -38,7 +38,7 @@ namespace OpenTK.Platform.Egl
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
{
EGLConfig[] configs = new EGLConfig[1];
IntPtr[] configs = new IntPtr[1];
int[] attribList = new int[]
{
//Egl.SURFACE_TYPE, Egl.WINDOW_BIT,
@ -58,7 +58,7 @@ namespace OpenTK.Platform.Egl
};
// Todo: what if we don't wish to use the default display?
EGLDisplay display = Egl.GetDisplay(EGLNativeDisplayType.Default);
IntPtr display = Egl.GetDisplay(IntPtr.Zero);
int major, minor;
if (!Egl.Initialize(display, out major, out minor))
throw new GraphicsModeException(String.Format("Failed to initialize display connection, error {0}", Egl.GetError()));
@ -75,7 +75,7 @@ namespace OpenTK.Platform.Egl
}
// See what we really got
EGLConfig active_config = configs[0];
IntPtr active_config = configs[0];
int r, g, b, a;
Egl.GetConfigAttrib(display, active_config, Egl.RED_SIZE, out r);
Egl.GetConfigAttrib(display, active_config, Egl.GREEN_SIZE, out g);
@ -88,7 +88,7 @@ namespace OpenTK.Platform.Egl
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out sample_buffers);
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out samples);
return new GraphicsMode(active_config.Handle.Value, new ColorFormat(r, g, b, a), d, s, sample_buffers > 0 ? samples : 0, 0, 2, false);
return new GraphicsMode(active_config, new ColorFormat(r, g, b, a), d, s, sample_buffers > 0 ? samples : 0, 0, 2, false);
}
#endregion

View file

@ -37,10 +37,12 @@ namespace OpenTK.Platform.Egl
// EGL factory for the Windows platform.
class EglWinPlatformFactory : WinFactory
{
#region Public Members
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{
WinWindowInfo win_win = (WinWindowInfo)window;
EGLDisplay egl_display = Egl.GetDisplay(EGLNativeDisplayType.Default); // Egl.GetDisplay(new EGLNativeDisplayType(win_win.DeviceContext));
IntPtr egl_display = GetDisplay(win_win.DeviceContext);
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(win_win.WindowHandle, egl_display);
return new EglContext(mode, egl_win, shareContext, major, minor, flags);
}
@ -48,14 +50,37 @@ namespace OpenTK.Platform.Egl
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{
WinWindowInfo win_win = (WinWindowInfo)window;
EGLDisplay egl_display = Egl.GetDisplay(EGLNativeDisplayType.Default); // Egl.GetDisplay(new EGLNativeDisplayType(win_win.DeviceContext));
IntPtr egl_display = GetDisplay(win_win.DeviceContext);
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(win_win.WindowHandle, egl_display);
return new EglContext(handle, egl_win, shareContext, major, minor, flags);
}
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
{
return (GraphicsContext.GetCurrentContextDelegate)delegate
{
return new ContextHandle(Egl.GetCurrentContext());
};
}
public override IGraphicsMode CreateGraphicsMode()
{
return new EglGraphicsMode();
}
#endregion
#region Private Members
IntPtr GetDisplay(IntPtr dc)
{
IntPtr display = Egl.GetDisplay(dc);
if (display == IntPtr.Zero)
display = Egl.GetDisplay(IntPtr.Zero);
return display;
}
#endregion
}
}

View file

@ -39,21 +39,21 @@ namespace OpenTK.Platform.Egl
#region Fields
IntPtr handle;
EGLDisplay display;
EGLSurface surface;
IntPtr display;
IntPtr surface;
bool disposed;
#endregion
#region Constructiors
public EglWindowInfo(IntPtr handle, EGLDisplay display)
public EglWindowInfo(IntPtr handle, IntPtr display)
{
Handle = handle;
Display = display;
}
public EglWindowInfo(IntPtr handle, EGLDisplay display, EGLSurface surface)
public EglWindowInfo(IntPtr handle, IntPtr display, IntPtr surface)
{
Handle = handle;
Display = display;
@ -66,11 +66,11 @@ namespace OpenTK.Platform.Egl
public IntPtr Handle { get { return handle; } private set { handle = value; } }
public EGLDisplay Display { get { return display; } private set { display = value; } }
public IntPtr Display { get { return display; } private set { display = value; } }
public EGLSurface Surface { get { return surface; } private set { surface = value; } }
public IntPtr Surface { get { return surface; } private set { surface = value; } }
public void CreateWindowSurface(EGLConfig config)
public void CreateWindowSurface(IntPtr config)
{
Surface = Egl.CreateWindowSurface(Display, config, Handle, null);
int error = Egl.GetError();
@ -90,7 +90,7 @@ namespace OpenTK.Platform.Egl
public void DestroySurface()
{
if (Surface.Handle != EGLSurface.None.Handle)
if (Surface != IntPtr.Zero)
if (!Egl.DestroySurface(Display, Surface))
Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface);
}

View file

@ -38,15 +38,23 @@ namespace OpenTK.Platform.Egl
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{
X11WindowInfo x11_win = (X11WindowInfo)window;
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.WindowHandle, Egl.GetDisplay(new EGLNativeDisplayType(x11_win.Display)));
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.WindowHandle, Egl.GetDisplay(x11_win.Display));
return new EglContext(mode, egl_win, shareContext, major, minor, flags);
}
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{
X11WindowInfo x11_win = (X11WindowInfo)window;
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.WindowHandle, Egl.GetDisplay(new EGLNativeDisplayType(x11_win.Display)));
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.WindowHandle, Egl.GetDisplay(x11_win.Display));
return new EglContext(handle, egl_win, shareContext, major, minor, flags);
}
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
{
return (GraphicsContext.GetCurrentContextDelegate)delegate
{
return new ContextHandle(Egl.GetCurrentContext());
};
}
}
}

View file

@ -32,6 +32,8 @@ namespace OpenTK.Platform.MacOS
GraphicsMode graphics_mode;
CarbonWindowInfo carbonWindow;
IntPtr shareContextRef;
DisplayDevice device;
bool mIsFullscreen = false;
public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext)
{
@ -43,7 +45,19 @@ namespace OpenTK.Platform.MacOS
if (shareContext is AglContext)
shareContextRef = ((AglContext)shareContext).Handle.Handle;
if (shareContext is GraphicsContext)
{
ContextHandle shareHandle = shareContext != null ?
(shareContext as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
shareContextRef = shareHandle.Handle;
}
if (shareContextRef == IntPtr.Zero)
{
Debug.Print("No context sharing will take place.");
}
CreateContext(mode, carbonWindow, shareContextRef, true);
}
@ -76,7 +90,7 @@ namespace OpenTK.Platform.MacOS
IntPtr shareContextRef, bool fullscreen)
{
List<int> aglAttributes = new List<int>();
Debug.Print("AGL pixel format attributes:");
Debug.Indent();
@ -101,7 +115,7 @@ namespace OpenTK.Platform.MacOS
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_ALPHA_SIZE, mode.AccumulatorFormat.Alpha);
}
if (mode.Samples > 0)
if (mode.Samples > 1)
{
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLE_BUFFERS_ARB, 1);
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLES_ARB, mode.Samples);
@ -160,8 +174,10 @@ namespace OpenTK.Platform.MacOS
MyAGLReportError("aglChoosePixelFormat");
}
Debug.Print("Creating AGL context. Sharing with {0}", shareContextRef);
// create the context and share it with the share reference.
Handle = new ContextHandle( Agl.aglCreateContext(myAGLPixelFormat, shareContextRef));
MyAGLReportError("aglCreateContext");
@ -243,6 +259,7 @@ namespace OpenTK.Platform.MacOS
void SetDrawable(CarbonWindowInfo carbonWindow)
{
IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow);
//Debug.Print("Setting drawable for context {0} to window port: {1}", Handle.Handle, windowPort);
Agl.aglSetDrawable(Handle.Handle, windowPort);
@ -261,18 +278,58 @@ namespace OpenTK.Platform.MacOS
}
else
windowPort = API.GetWindowPort(carbonWindow.WindowRef);
return windowPort;
}
public override void Update(IWindowInfo window)
{
CarbonWindowInfo carbonWindow = (CarbonWindowInfo)window;
if (carbonWindow.GoFullScreenHack)
{
carbonWindow.GoFullScreenHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null)
wind.SetFullscreen(this);
else
Debug.Print("Could not find window!");
return;
}
else if (carbonWindow.GoWindowedHack)
{
carbonWindow.GoWindowedHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null)
wind.UnsetFullscreen(this);
else
Debug.Print("Could not find window!");
}
if (mIsFullscreen)
return;
SetDrawable(carbonWindow);
SetBufferRect(carbonWindow);
Agl.aglUpdateContext(Handle.Handle);
}
private CarbonGLNative GetCarbonWindow(CarbonWindowInfo carbonWindow)
{
WeakReference r = CarbonGLNative.WindowRefMap[carbonWindow.WindowRef];
if (r.IsAlive)
{
return (CarbonGLNative) r.Target;
}
else
return null;
}
void MyAGLReportError(string function)
{
Agl.AglError err = Agl.GetError();
@ -285,24 +342,43 @@ namespace OpenTK.Platform.MacOS
bool firstFullScreen = false;
internal void SetFullScreen(CarbonWindowInfo info)
internal void SetFullScreen(CarbonWindowInfo info, out int width, out int height)
{
Agl.aglSetFullScreen(Handle.Handle, 0, 0, 0, 0);
CarbonGLNative wind = GetCarbonWindow(info);
Debug.Print("Switching to full screen {0}x{1} on context {2}",
wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, Handle.Handle);
CG.DisplayCapture(GetQuartzDevice(info));
Agl.aglSetFullScreen(Handle.Handle, wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, 0, 0);
MakeCurrent(info);
width = wind.TargetDisplayDevice.Width;
height = wind.TargetDisplayDevice.Height;
// This is a weird hack to workaround a bug where the first time a context
// is made fullscreen, we just end up with a blank screen. So we undo it as fullscreen
// and redo it as fullscreen.
if (firstFullScreen == false)
{
firstFullScreen = true;
UnsetFullScreen(info);
SetFullScreen(info);
}
if (firstFullScreen == false)
{
firstFullScreen = true;
UnsetFullScreen(info);
SetFullScreen(info, out width, out height);
}
mIsFullscreen = true;
}
internal void UnsetFullScreen(CarbonWindowInfo windowInfo)
{
Debug.Print("Unsetting AGL fullscreen.");
Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero);
SetDrawable(windowInfo);
Agl.aglUpdateContext(Handle.Handle);
CG.DisplayRelease(GetQuartzDevice(windowInfo));
Debug.Print("Resetting drawable.");
SetDrawable(windowInfo);
mIsFullscreen = false;
}

View file

@ -44,9 +44,6 @@ namespace OpenTK.Platform.MacOS
CarbonWindowInfo window;
CarbonInput mInputDriver;
[Obsolete]
GraphicsContext context;
static MacOSKeyMap Keymap = new MacOSKeyMap();
IntPtr uppHandler;
@ -107,11 +104,11 @@ namespace OpenTK.Platform.MacOS
public CarbonGLNative(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
{
CreateNativeWindow(WindowClass.Document,
CreateNativeWindow(WindowClass.Document,
WindowAttributes.StandardDocument | WindowAttributes.StandardHandler |
WindowAttributes.InWindowMenu | WindowAttributes.LiveResize,
new Rect((short)x, (short)y, (short)width, (short)height));
mDisplayDevice = device;
}
@ -252,23 +249,32 @@ namespace OpenTK.Platform.MacOS
API.HideWindow(window.WindowRef);
}
void SetFullscreen()
internal void SetFullscreen(AglContext context)
{
windowedBounds = bounds;
((AglContext)(context as IGraphicsContextInternal).Implementation).SetFullScreen(window);
int width, height;
context.SetFullScreen(window, out width, out height);
Debug.Print("Prev Size: {0}, {1}", Width, Height);
clientRectangle.Size = new Size(width, height);
Debug.Print("New Size: {0}, {1}", Width, Height);
// TODO: if we go full screen we need to make this use the device specified.
bounds = DisplayDevice.Default.Bounds;
bounds = mDisplayDevice.Bounds;
Debug.Print("New Size: {0}, {1}", Width, Height);
windowState = WindowState.Fullscreen;
}
void UnsetFullscreen()
internal void UnsetFullscreen(AglContext context)
{
((AglContext)(context as IGraphicsContextInternal).Implementation).UnsetFullScreen(window);
context.UnsetFullScreen(window);
Debug.Print("Telling Carbon to reset window state to " + windowState.ToString());
SetCarbonWindowState();
SetSize((short)windowedBounds.Width, (short)windowedBounds.Height);
}
@ -371,16 +377,16 @@ namespace OpenTK.Platform.MacOS
case KeyboardEventKind.RawKeyDown:
OnKeyPress(mKeyPressArgs);
InputDriver.Keyboard[0][Keymap[code]] = true;
return OSStatus.EventNotHandled;
return OSStatus.NoError;
case KeyboardEventKind.RawKeyUp:
InputDriver.Keyboard[0][Keymap[code]] = false;
return OSStatus.EventNotHandled;
return OSStatus.NoError;
case KeyboardEventKind.RawKeyModifiersChanged:
ProcessModifierKey(inEvent);
return OSStatus.EventNotHandled;
return OSStatus.NoError;
default:
return OSStatus.EventNotHandled;
@ -679,26 +685,9 @@ namespace OpenTK.Platform.MacOS
#endregion
#region INativeGLWindow Members
#region INativeWindow Members
public void CreateWindow(int width, int height, GraphicsMode mode, int major, int minor, GraphicsContextFlags flags, out IGraphicsContext context)
{
Rect r = new Rect(0, 0, (short)width, (short)height);
CreateNativeWindow(mWindowClass, mWindowAttrib, r);
Show();
this.context = new GraphicsContext(mode, window, major, minor, flags);
this.context.MakeCurrent(window);
context = this.context;
}
public void DestroyWindow()
{
Dispose();
}
public void ProcessEvents()
public void ProcessEvents()
{
Application.ProcessEvents();
}
@ -708,13 +697,18 @@ namespace OpenTK.Platform.MacOS
IntPtr handle = window.WindowRef;
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
Console.WriteLine("Rect: {0}", r);
Debug.Print("Rect: {0}", r);
return new Point(point.X - r.X, point.Y - r.Y);
}
public Point PointToScreen(Point point)
{
throw new NotImplementedException();
IntPtr handle = window.WindowRef;
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
Debug.Print("Rect: {0}", r);
return new Point(point.X + r.X, point.Y + r.Y);
}
public bool Exists
@ -740,21 +734,6 @@ namespace OpenTK.Platform.MacOS
}
}
public bool Fullscreen
{
get
{
return false;
}
set
{
throw new NotImplementedException();
}
}
#endregion
#region INativeWindow Members
public Icon Icon
{
@ -969,7 +948,6 @@ namespace OpenTK.Platform.MacOS
if (Carbon.API.IsWindowCollapsed(window.WindowRef))
return WindowState.Minimized;
if (Carbon.API.IsWindowInStandardState(window.WindowRef))
{
return WindowState.Maximized;
@ -983,81 +961,94 @@ namespace OpenTK.Platform.MacOS
return;
Debug.Print("Switching window state from {0} to {1}", WindowState, value);
WindowState oldState = WindowState;
if (WindowState == WindowState.Fullscreen)
windowState = value;
if (oldState == WindowState.Fullscreen)
{
UnsetFullscreen();
window.GoWindowedHack = true;
// when returning from full screen, wait until the context is updated
// to actually do the work.
return;
}
if (WindowState == WindowState.Minimized)
if (oldState == WindowState.Minimized)
{
API.CollapseWindow(window.WindowRef, false);
}
CarbonPoint idealSize;
switch (value)
{
case WindowState.Fullscreen:
SetFullscreen();
break;
case WindowState.Maximized:
// hack because mac os has no concept of maximized. Instead windows are "zoomed"
// meaning they are maximized up to their reported ideal size. So we report a
// large ideal size.
idealSize = new CarbonPoint(9000, 9000);
API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomOut, ref idealSize);
break;
case WindowState.Normal:
if (WindowState == WindowState.Maximized)
{
idealSize = new CarbonPoint();
API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomIn, ref idealSize);
}
break;
case WindowState.Minimized:
API.CollapseWindow(window.WindowRef, true);
break;
}
windowState = value;
OnWindowStateChanged();
OnResize();
SetCarbonWindowState();
}
}
public WindowBorder WindowBorder
{
get
{
return windowBorder;
}
set
{
if (windowBorder != value)
{
windowBorder = value;
private void SetCarbonWindowState()
{
CarbonPoint idealSize;
if (windowBorder == WindowBorder.Resizable)
{
API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.Resizable | WindowAttributes.FullZoom,
WindowAttributes.NoAttributes);
}
else if (windowBorder == WindowBorder.Fixed)
{
API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.NoAttributes,
WindowAttributes.Resizable | WindowAttributes.FullZoom);
}
switch (windowState)
{
case WindowState.Fullscreen:
window.GoFullScreenHack = true;
if (WindowBorderChanged != null)
WindowBorderChanged(this, EventArgs.Empty);
}
}
break;
case WindowState.Maximized:
// hack because mac os has no concept of maximized. Instead windows are "zoomed"
// meaning they are maximized up to their reported ideal size. So we report a
// large ideal size.
idealSize = new CarbonPoint(9000, 9000);
API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomOut, ref idealSize);
break;
case WindowState.Normal:
if (WindowState == WindowState.Maximized)
{
idealSize = new CarbonPoint();
API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomIn, ref idealSize);
}
break;
case WindowState.Minimized:
API.CollapseWindow(window.WindowRef, true);
break;
}
OnWindowStateChanged();
OnResize();
}
public WindowBorder WindowBorder
{
get
{
return windowBorder;
}
set
{
if (windowBorder == value)
return;
windowBorder = value;
if (windowBorder == WindowBorder.Resizable)
{
API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.Resizable | WindowAttributes.FullZoom,
WindowAttributes.NoAttributes);
}
else if (windowBorder == WindowBorder.Fixed)
{
API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.NoAttributes,
WindowAttributes.Resizable | WindowAttributes.FullZoom);
}
if (WindowBorderChanged != null)
WindowBorderChanged(this, EventArgs.Empty);
}
}
#region --- Event wrappers ---

View file

@ -41,6 +41,8 @@ namespace OpenTK.Platform.MacOS
bool ownHandle = false;
bool disposed = false;
bool isControl = false;
bool goFullScreenHack = false;
bool goWindowedHack = false;
#region Constructors
@ -69,6 +71,18 @@ namespace OpenTK.Platform.MacOS
get { return this.windowRef; }
}
internal bool GoFullScreenHack
{
get { return goFullScreenHack; }
set { goFullScreenHack = value; }
}
internal bool GoWindowedHack
{
get { return goWindowedHack; }
set { goWindowedHack = value; }
}
/// <summary>
/// Gets a value indicating whether this instance refers to a System.Windows.Forms.Control.
/// </summary>

View file

@ -844,6 +844,9 @@ namespace OpenTK.Platform.Windows
#endregion
[DllImport("user32.dll", SetLastError=true)]
public static extern BOOL SetForegroundWindow(HWND hWnd);
#endregion
#region Display settings

View file

@ -68,6 +68,7 @@ namespace OpenTK.Platform.Windows
WindowState windowState = WindowState.Normal;
bool borderless_maximized_window_state = false; // Hack to get maximized mode with hidden border (not normally possible).
bool focused;
bool mouse_outside_window = true;
Rectangle
bounds = new Rectangle(),
@ -75,8 +76,7 @@ namespace OpenTK.Platform.Windows
previous_bounds = new Rectangle(); // Used to restore previous size when leaving fullscreen mode.
Icon icon;
const ClassStyle DefaultClassStyle =
ClassStyle.OwnDC | ClassStyle.VRedraw | ClassStyle.HRedraw | ClassStyle.Ime;
const ClassStyle DefaultClassStyle = ClassStyle.OwnDC;
readonly IntPtr DefaultWindowProcedure =
Marshal.GetFunctionPointerForDelegate(new WindowProcedure(Functions.DefWindowProc));
@ -140,8 +140,6 @@ namespace OpenTK.Platform.Windows
keyboards.Add(keyboard);
mice.Add(mouse);
EnableMouseLeaveNotifications();
}
#endregion
@ -184,22 +182,6 @@ namespace OpenTK.Platform.Windows
StopTimer(handle);
break;
case WindowMessage.NCCALCSIZE:
// Need to update the client rectangle, because it has the wrong size on Vista with Aero enabled.
//if (m.WParam == new IntPtr(1))
//{
// unsafe
// {
// NcCalculateSize* nc_calc_size = (NcCalculateSize*)m.LParam;
// //nc_calc_size->NewBounds = nc_calc_size->OldBounds;
// //nc_calc_size->OldBounds = nc_calc_size->NewBounds;
// //client_rectangle = rect.OldClientRectangle;
// }
// m.Result = new IntPtr((int)(NcCalcSizeOptions.ALIGNTOP | NcCalcSizeOptions.ALIGNLEFT/* | NcCalcSizeOptions.REDRAW*/));
//}
break;
case WindowMessage.ERASEBKGND:
return new IntPtr(1);
@ -296,23 +278,27 @@ namespace OpenTK.Platform.Windows
(short)((uint)lParam.ToInt32() & 0x0000FFFF),
(short)(((uint)lParam.ToInt32() & 0xFFFF0000) >> 16));
mouse.Position = point;
if (mouse_outside_window)
{
if (!ClientRectangle.Contains(point))
{
Functions.ReleaseCapture();
if (MouseLeave != null)
MouseLeave(this, EventArgs.Empty);
}
else if (Functions.GetCapture() != window.WindowHandle)
{
Functions.SetFocus(window.WindowHandle);
Functions.SetCapture(window.WindowHandle);
if (MouseEnter != null)
MouseEnter(this, EventArgs.Empty);
}
// Once we receive a mouse move event, it means that the mouse has
// re-entered the window.
mouse_outside_window = false;
EnableMouseTracking();
if (MouseEnter != null)
MouseEnter(this, EventArgs.Empty);
}
break;
case WindowMessage.MOUSELEAVE:
mouse_outside_window = true;
// Mouse tracking is disabled automatically by the OS
if (MouseLeave != null)
MouseLeave(this, EventArgs.Empty);
break;
case WindowMessage.MOUSEWHEEL:
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
@ -454,6 +440,8 @@ namespace OpenTK.Platform.Windows
Win32Rectangle rect;
Functions.GetClientRect(handle, out rect);
client_rectangle = rect.ToRectangle();
Functions.SetForegroundWindow(handle);
}
break;
@ -478,7 +466,6 @@ namespace OpenTK.Platform.Windows
exists = false;
Functions.UnregisterClass(ClassName, Instance);
//Marshal.FreeHGlobal(ClassName);
window.Dispose();
child_window.Dispose();
@ -493,6 +480,18 @@ namespace OpenTK.Platform.Windows
return Functions.DefWindowProc(handle, message, wParam, lParam);
}
private void EnableMouseTracking()
{
TrackMouseEventStructure me = new TrackMouseEventStructure();
me.Size = TrackMouseEventStructure.SizeInBytes;
me.TrackWindowHandle = child_window.WindowHandle;
me.Flags = TrackMouseEventFlags.LEAVE;
if (!Functions.TrackMouseEvent(ref me))
Debug.Print("[Warning] Failed to enable mouse tracking, error: {0}.",
Marshal.GetLastWin32Error());
}
private void StartTimer(IntPtr handle)
{
if (timer_handle == UIntPtr.Zero)
@ -610,18 +609,6 @@ namespace OpenTK.Platform.Windows
#endregion
void EnableMouseLeaveNotifications()
{
TrackMouseEventStructure tme = new TrackMouseEventStructure();
tme.Size = TrackMouseEventStructure.SizeInBytes;
tme.Flags |= TrackMouseEventFlags.LEAVE;
tme.TrackWindowHandle = child_window.WindowHandle;
tme.HoverTime = -1; // HOVER_DEFAULT
if (!Functions.TrackMouseEvent(ref tme))
Debug.Print("[Error] Failed to enable mouse event tracking. Error: {0}",
Marshal.GetLastWin32Error());
}
#endregion
#region INativeWindow Members
@ -682,7 +669,7 @@ namespace OpenTK.Platform.Windows
}
set
{
Size = value.Size;
ClientSize = value.Size;
}
}
@ -905,6 +892,8 @@ namespace OpenTK.Platform.Windows
WindowBorder = WindowBorder.Hidden;
command = ShowWindowCommand.MAXIMIZE;
Functions.SetForegroundWindow(window.WindowHandle);
break;
}
@ -953,6 +942,11 @@ namespace OpenTK.Platform.Windows
if (windowBorder == value)
return;
// We wish to avoid making an invisible window visible just to change the border.
// However, it's a good idea to make a visible window invisible temporarily, to
// avoid garbage caused by the border change.
bool was_visible = Visible;
// To ensure maximized/minimized windows work correctly, reset state to normal,
// change the border, then go back to maximized/minimized.
WindowState state = WindowState;
@ -982,7 +976,8 @@ namespace OpenTK.Platform.Windows
Functions.AdjustWindowRectEx(ref rect, style, false, ParentStyleEx);
// This avoids leaving garbage on the background window.
Visible = false;
if (was_visible)
Visible = false;
Functions.SetWindowLong(window.WindowHandle, GetWindowLongOffsets.STYLE, (IntPtr)(int)style);
Functions.SetWindowPos(window.WindowHandle, IntPtr.Zero, 0, 0, rect.Width, rect.Height,
@ -992,7 +987,7 @@ namespace OpenTK.Platform.Windows
// Force window to redraw update its borders, but only if it's
// already visible (invisible windows will change borders when
// they become visible, so no need to make them visiable prematurely).
if (Visible)
if (was_visible)
Visible = true;
WindowState = state;

View file

@ -252,6 +252,7 @@ namespace OpenTK.Platform.X11
#endregion
/// \internal
/// <summary>
/// Provides access to GLX functions.
/// </summary>

View file

@ -14,6 +14,7 @@ using OpenTK.Graphics;
namespace OpenTK.Platform.X11
{
/// \internal
/// <summary>
/// Provides methods to create and control an opengl context on the X11 platform.
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
@ -370,7 +371,7 @@ namespace OpenTK.Platform.X11
{
IntPtr display = Display;
if (IsCurrent)
MakeCurrent(null);
Glx.MakeCurrent(display, IntPtr.Zero, IntPtr.Zero);
Glx.DestroyContext(display, Handle);
}

View file

@ -38,6 +38,7 @@ using System.Drawing;
namespace OpenTK.Platform.X11
{
/// \internal
/// <summary>
/// Drives GameWindow on X11.
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
@ -148,7 +149,8 @@ namespace OpenTK.Platform.X11
EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeymapStateMask |
EventMask.PointerMotionMask | EventMask.FocusChangeMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask |
EventMask.EnterWindowMask | EventMask.LeaveWindowMask;
EventMask.EnterWindowMask | EventMask.LeaveWindowMask |
EventMask.PropertyChangeMask;
attributes.event_mask = (IntPtr)window.EventMask;
uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
@ -237,25 +239,25 @@ namespace OpenTK.Platform.X11
Debug.WriteLine("Registering atoms.");
_atom_wm_destroy = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true);
_atom_net_wm_state = Functions.XInternAtom(window.Display, "_NET_WM_STATE", false);
_atom_net_wm_state = Functions.XInternAtom(window.Display, "_NET_WM_STATE", false);
_atom_net_wm_state_minimized = Functions.XInternAtom(window.Display, "_NET_WM_STATE_MINIMIZED", false);
_atom_net_wm_state_fullscreen = Functions.XInternAtom(window.Display, "_NET_WM_STATE_FULLSCREEN", false);
_atom_net_wm_state_maximized_horizontal =
Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
_atom_net_wm_state_maximized_vertical =
Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_VERT", false);
Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_VERT", false);
_atom_net_wm_allowed_actions =
Functions.XInternAtom(window.Display, "_NET_WM_ALLOWED_ACTIONS", false);
_atom_net_wm_allowed_actions =
Functions.XInternAtom(window.Display, "_NET_WM_ALLOWED_ACTIONS", false);
_atom_net_wm_action_resize =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_RESIZE", false);
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_RESIZE", false);
_atom_net_wm_action_maximize_horizontally =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_HORZ", false);
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_HORZ", false);
_atom_net_wm_action_maximize_vertically =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_VERT", false);
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_VERT", false);
_atom_net_wm_icon =
Functions.XInternAtom(window.Display, "_NEW_WM_ICON", false);
_atom_net_wm_icon =
Functions.XInternAtom(window.Display, "_NEW_WM_ICON", false);
// string[] atom_names = new string[]
// {
@ -624,9 +626,6 @@ namespace OpenTK.Platform.X11
{
isExiting = true;
if (Unload != null)
Unload(this, EventArgs.Empty);
Debug.WriteLine("Destroying window.");
Functions.XDestroyWindow(window.Display, window.WindowHandle);
break;
@ -740,6 +739,12 @@ namespace OpenTK.Platform.X11
Functions.XRefreshKeyboardMapping(ref e.MappingEvent);
}
break;
case XEventName.PropertyNotify:
if (e.PropertyEvent.atom == _atom_net_wm_state)
if (WindowStateChanged != null)
WindowStateChanged(this, EventArgs.Empty);
break;
default:
//Debug.WriteLine(String.Format("{0} event was not handled", e.type));
@ -980,7 +985,8 @@ namespace OpenTK.Platform.X11
{
Functions.XGetWindowProperty(window.Display, window.WindowHandle,
_atom_net_wm_state, IntPtr.Zero, new IntPtr(256), false,
IntPtr.Zero, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
new IntPtr(4) /*XA_ATOM*/, out actual_atom, out actual_format,
out nitems, out bytes_after, ref prop);
}
if ((long)nitems > 0 && prop != IntPtr.Zero)
@ -1029,6 +1035,7 @@ namespace OpenTK.Platform.X11
using (new XLock(window.Display))
{
// Reset the current window state
if (current_state == OpenTK.WindowState.Minimized)
Functions.XMapWindow(window.Display, window.WindowHandle);
else if (current_state == OpenTK.WindowState.Fullscreen)
@ -1087,9 +1094,6 @@ namespace OpenTK.Platform.X11
if (temporary_resizable)
WindowBorder = previous_state;
if (WindowStateChanged != null)
WindowStateChanged(this, EventArgs.Empty);
}
}
@ -1209,15 +1213,6 @@ namespace OpenTK.Platform.X11
#endregion
#region public bool IsExiting
public bool IsExiting
{
get { return isExiting; }
}
#endregion
#region public bool IsIdle
public bool IsIdle
@ -1227,65 +1222,6 @@ namespace OpenTK.Platform.X11
#endregion
#region public bool Fullscreen
public bool Fullscreen
{
get
{
return false;
//return fullscreen;
}
set
{
// if (value && !fullscreen)
// {
// Debug.Print("Going fullscreen");
// Debug.Indent();
// DisableWindowDecorations();
// pre_fullscreen_height = this.Height;
// pre_fullscreen_width = this.Width;
// //Functions.XRaiseWindow(this.window.Display, this.Handle);
// Functions.XMoveResizeWindow(this.window.Display, this.Handle, 0, 0,
// DisplayDevice.Default.Width, DisplayDevice.Default.Height);
// Debug.Unindent();
// fullscreen = true;
// }
// else if (!value && fullscreen)
// {
// Debug.Print("Going windowed");
// Debug.Indent();
// Functions.XMoveResizeWindow(this.window.Display, this.Handle, 0, 0,
// pre_fullscreen_width, pre_fullscreen_height);
// pre_fullscreen_height = pre_fullscreen_width = 0;
// EnableWindowDecorations();
// Debug.Unindent();
// fullscreen = false;
// }
/*
Debug.Print(value ? "Going fullscreen" : "Going windowed");
IntPtr state_atom = Functions.XInternAtom(this.window.Display, "_NET_WM_STATE", false);
IntPtr fullscreen_atom = Functions.XInternAtom(this.window.Display, "_NET_WM_STATE_FULLSCREEN", false);
XEvent xev = new XEvent();
xev.ClientMessageEvent.type = XEventName.ClientMessage;
xev.ClientMessageEvent.serial = IntPtr.Zero;
xev.ClientMessageEvent.send_event = true;
xev.ClientMessageEvent.window = this.Handle;
xev.ClientMessageEvent.message_type = state_atom;
xev.ClientMessageEvent.format = 32;
xev.ClientMessageEvent.ptr1 = (IntPtr)(value ? NetWindowManagerState.Add : NetWindowManagerState.Remove);
xev.ClientMessageEvent.ptr2 = (IntPtr)(value ? 1 : 0);
xev.ClientMessageEvent.ptr3 = IntPtr.Zero;
Functions.XSendEvent(this.window.Display, API.RootWindow, false,
(IntPtr)(EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask), ref xev);
fullscreen = !fullscreen;
*/
}
}
#endregion
#region public IntPtr Handle
/// <summary>
@ -1455,10 +1391,7 @@ namespace OpenTK.Platform.X11
while (Exists)
ProcessEvents();
}
if (GraphicsContext.CurrentContext != null)
GraphicsContext.CurrentContext.MakeCurrent(null);
window.Dispose();
window = null;
}

View file

@ -15,6 +15,7 @@ using System.Drawing;
namespace OpenTK.Platform.X11
{
/// \internal
/// <summary>
/// Drives the InputDriver on X11.
/// This class supports OpenTK, and is not intended for users of OpenTK.

View file

@ -31,6 +31,7 @@ using System.Text;
namespace OpenTK.Platform.X11
{
/// \internal
/// <summary>Describes an X11 window.</summary>
sealed class X11WindowInfo : IWindowInfo
{