Synced with 1.0 branch.

This commit is contained in:
the_fiddler 2010-03-11 22:53:11 +00:00
parent 803636ea95
commit 3f8f9b09e3
32 changed files with 3203 additions and 453 deletions

BIN
Build.exe

Binary file not shown.

View file

@ -1,3 +1,372 @@
---------------------------------
OpenTK 1.0 beta-2 -> 1.0 beta-3
---------------------------------
2010-03-09 the_fiddler
* Source/Compatibility/Properties/AssemblyInfo.cs,
Source/Examples/Properties/AssemblyInfo.cs,
Source/GLControl/Properties/AssemblyInfo.cs,
Source/OpenTK/Properties/AssemblyInfo.cs: Updated version numbers
for 1.0-beta3 release.
2010-03-05 the_fiddler
* Build.exe: Added error messages for missing doxygen or latex
installations.
* Source/Build/Build.cs: Added error messages for missing doxygen
or latex installations.
* Source/OpenTK/Platform/X11/Functions.cs: Removed unused code.
* Source/OpenTK/Platform/X11/API.cs,
Source/OpenTK/Platform/X11/X11GLContext.cs,
Source/OpenTK/Platform/X11/X11GLNative.cs,
Source/OpenTK/Platform/X11/X11GraphicsMode.cs: Ensure that all X
function calls are protected by XLockDisplay/XUnlockDisplay.
Fixed nasty deadlock bug due to (incorrectly) nested XLockDisplay
calls. Removed XLockDisplay from methods that do not use a
display connection.
* Source/OpenTK/GameWindow.cs: Do not access VSync property without
checking for a current context (avoids
GraphicsContextMissingException when the user moves the context
to its own rendering thread.)
* Source/Examples/OpenGL/1.5/VertexBufferObject.cs,
Source/Examples/OpenTK/GameWindow/ThreadedRendering.cs,
Source/Examples/Shapes/VertexPositionColor.cs: Added example for
threaded rendering (where OpenGL rendering is performed on its
own thread.) Moved VertexPositionColor struct to its own file, to
simplify sharing between samples.
* Source/Examples/Main.cs: Added missing license information.
* Source/OpenTK/Platform/X11/Bindings/Glx.cs: * Glx.cs: Do not use
ContextHandle directly as a p/invoke parameter (not portable).
* Source/OpenTK/Platform/Dummy/DummyGLContext.cs,
Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs,
Source/OpenTK/Platform/Windows/API.cs,
Source/OpenTK/Platform/Windows/WinGLContext.cs,
Source/OpenTK/Platform/Windows/WinGLNative.cs,
Source/OpenTK/Platform/Windows/WinRawMouse.cs,
Source/OpenTK/Platform/Windows/WinWindowInfo.cs: Marked internal
documentation as such, to avoid littering doxygen output.
* Source/Examples/OpenTK/Test/GameWindowStates.cs: * Minor code
cleanup and reorganization. * Added support for changing the
window size via + and - keys. * Moved key handling to the KeyDown
event. The user can now press and hold a key to observe how the
GameWindow reacts.
* Source/OpenTK/Platform/X11/X11GLNative.cs: * Protect all xlib
calls by XLockDisplay/XUnlockDisplay. * Remove
SubstructureNotifyMask, as we are not creating any child windows.
* Return ClientSize instead of Bounds.Size and Location instead
of Bounds.Location for the Size and Location properties
respectively. This aligns the implementation of these properties
on win32 and x11.
2010-03-02 the_fiddler
* Source/Compatibility/Properties/AssemblyInfo.cs,
Source/Examples/Properties/AssemblyInfo.cs,
Source/GLControl/Properties/AssemblyInfo.cs,
Source/OpenTK/Properties/AssemblyInfo.cs: Bumped version numbers
for release.
* Source/OpenTK/Platform/Windows/WinGLNative.cs: X and Y properties
now correctly get and set the window location on screen.
* Source/Examples/OpenTK/Test/GameWindowStates.cs: Allow arrow keys
to move the window around the screen.
* Source/OpenTK/Graphics/OpenGL/GLHelper.cs: Added overloads for
Vector[234]d and Matrix4d for a large number of helper functions.
Fixes issue [#1596]: "Vector3d and Vector2d support in Functions
like GL.Vertex3(), GL.Color3(), GL.TexCoord2() etc.".
* Source/OpenTK/GameWindow.cs: Replaced tabs with spaces.
GameWindow no longer raises a Resize event before Load. This was
a hack that was introduced to work around some design limitations
in the early days of the library. These limitations no longer
hold (INativeWindow size is now set independently of the Resize
event), so the hack is no longer necessary. The To avoid breaking
existing applications, a Resize event is still raised
unconditionally after Load is complete.
* Source/Examples/OpenTK/Test/GameWindowStates.cs: Display
information on mouse location and window position/size.
* Source/OpenTK/NativeWindow.cs: Use retainEvents parameter
according to the documentation (parameter was left unused
before).
* Source/OpenTK/Platform/Windows/API.cs,
Source/OpenTK/Platform/Windows/WinGLNative.cs: Ensure window is
brought to the top of the z-order when it becomes visible for the
first time (typically when GameWindow.Run() is called.) Ensure
window bounds are correctly restored after leaving fullscreen
mode, by restoring window border before setting the bounds.
2010-02-06 the_fiddler
* Source/Build/Build.cs: * Build.cs: Corrected filename casing for
default doxygen target (should be Doxyfile, not DoxyFile).
2010-02-04 the_fiddler
* Build.exe: Updated with documentation support.
* Source/Build/Build.cs: Improved output messages when generating
documentation.
* Source/Build/Build.cs, Source/Build/Resources/DoxyFile.txt: Do
not report doxygen warnings. Run pdflatex and makeindex in quiet
mode.
* Source/Build/Build.cs,
Source/Build/Properties/Resources.Designer.cs,
Source/Build/Properties/Resources.resx,
Source/Build/Resources/DoxyFile.txt: Added support for 'doc'
target, which generates html and pdf documentation (requires
doxygen and latex). Fixed implementation of DeleteFiles and
DeleteDirectories.
* Documentation/Source: Removed empty source documentation
directory from source control. This directory is created as
necessary when generating documentation.
2010-02-03 the_fiddler
* Source/Bind/Specifications/GL2/enumext.spec,
Source/Bind/Specifications/GL2/gloverrides.xml,
Source/OpenTK/Graphics/OpenGL/GL.cs,
Source/OpenTK/Graphics/OpenGL/GLCore.cs,
Source/OpenTK/Graphics/OpenGL/GLDelegates.cs,
Source/OpenTK/Graphics/OpenGL/GLEnums.cs,
Source/OpenTK/Graphics/OpenGL/GLHelper.cs: Added explicit
ActiveUniformParameter enum for GetActiveUniforms function. Fixes
issue [#1443]: "GetActiveUniforms parameter name".
* Source/Bind/Specifications/GL2/enumext.spec,
Source/OpenTK/Graphics/OpenGL/GLEnums.cs: Added missing
TEXTURE_LOD_BIAS token to TextureParameterName. Fixes issue
[#1531]: "TextureParameterName enum missing TEXTURE_LOD_BIAS
element".
* Source/Bind/Specifications/GL2/enumext.spec,
Source/Bind/Specifications/GL2/gloverrides.xml,
Source/OpenTK/Graphics/OpenGL/GL.cs,
Source/OpenTK/Graphics/OpenGL/GLCore.cs,
Source/OpenTK/Graphics/OpenGL/GLDelegates.cs,
Source/OpenTK/Graphics/OpenGL/GLEnums.cs,
Source/OpenTK/Graphics/OpenGL/GLHelper.cs: Added specific
ArrayCap enum for Enable/DisableClientState. Fixes issue [#1538]:
"GLCore.cs: EnableClientState()".
* Source/OpenTK/Graphics/Color4.cs: Color4.ToArgb() should scale
components from clamped floats [0.0, 1.0] to unsigned bytes [0,
255]. Fixes issue [#1504]: "Color4.ToArgb returns wrong results".
* Source/OpenTK/Math/Vector2d.cs, Source/OpenTK/Math/Vector3d.cs,
Source/OpenTK/Math/Vector4d.cs: Converted single-precision
constants to double-precision in double-precision calculations.
* Source/OpenTK/Math/Vector2d.cs, Source/OpenTK/Math/Vector3d.cs,
Source/OpenTK/Math/Vector4d.cs: Do not cast to float when
calculating double-precision vector Length. Fixes issue [#1542]:
"Vector3d.Length casts result to float".
2010-01-28 kanato
* Source/OpenTK/Platform/MacOS/AglContext.cs,
Source/OpenTK/Platform/MacOS/CarbonGLNative.cs: Fix reported
Width, Height properties for full screen window.
* Source/OpenTK/GameWindow.cs: Correct NullReferenceException when
initializing GameWindow with GameWindowFlags.FullScreen.
2010-01-21 the_fiddler
* Source/OpenTK/Graphics/GraphicsContext.cs: Use the correct
GetCurrentContext() implementation depending on whether we are
using native or embedded (EGL) contexts.
2010-01-20 the_fiddler
* Source/OpenTK/Platform/Egl/EglWinPlatformFactory.cs,
Source/OpenTK/Platform/Egl/EglX11PlatformFactory.cs: Use
Egl.GetCurrentContext() instead of Wgl/Glx.GetCurrentContext() in
EglContext.
2010-01-11 kanato
* Source/OpenTK/Platform/MacOS/CarbonGLNative.cs: Backport
Width/Height fix (rev. 2577) for MacOS implementation.
2009-12-27 the_fiddler
* Source/OpenTK/Platform/Egl/EglContext.cs: Use the graphics mode
that was selected by EglGraphicsMode.SelectGraphicsMode() instead
of the native, platform-specific one. Fixes issue [#1483]: "ES20
application problem, Graphicmode with stencil buffer?"
* Source/OpenTK/Platform/Egl/EglWinPlatformFactory.cs: Try to
retrieve the EGL display for the current DC before falling back
to the default display.
* Source/OpenTK/Platform/Egl/Egl.cs,
Source/OpenTK/Platform/Egl/EglContext.cs,
Source/OpenTK/Platform/Egl/EglGraphicsMode.cs,
Source/OpenTK/Platform/Egl/EglWinPlatformFactory.cs,
Source/OpenTK/Platform/Egl/EglWindowInfo.cs,
Source/OpenTK/Platform/Egl/EglX11PlatformFactory.cs: Replaced
struct wrappers over IntPtr by plain IntPtr types. This should
ensure correct p/invoke behavior regardless of the OS/CPU.
* Source/OpenTK/GameWindow.cs: Avoid enabling VSync repeatedly,
when VSyncMode is Adaptive and TargetRenderPeriod is 0. Should
remove jitter observed on specific configurations. Solves issue
[#1482]: "OnRenderFrame elapsed time".
* Source/Examples/OpenGLES/2.0/SimpleWindow20.cs: Renamed, since
example doesn't use immediate mode. Removed unused code.
2009-12-26 the_fiddler
* Source/OpenTK/Audio/AudioContext.cs,
Source/OpenTK/Platform/X11/Bindings/Glx.cs,
Source/OpenTK/Platform/X11/X11GLContext.cs,
Source/OpenTK/Platform/X11/X11GLNative.cs,
Source/OpenTK/Platform/X11/X11Input.cs,
Source/OpenTK/Platform/X11/X11WindowInfo.cs: Marked as internal
so they don't appear in doxygen documentation.
2009-12-22 the_fiddler
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Avoid NRE when
setting the foreground window in WindowMessage.CREATE. Fixes
issue [#1467]: "Failure to initialize on Windows."
* Source/OpenTK/Input/MouseDevice.cs: Corrected rounding of
negative delta values. Fixes issue [#1446]:
"MouseWheelEventArgs.Delta".
2009-12-18 the_fiddler
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Calculate the
correct client rectangle when modifying width or height. Fixes
issue [#1457]: "GameWindow Width and Height properties are
inconsistent".
2009-12-15 the_fiddler
* Source/OpenTK/OpenTK.dll.config: Added missing OpenCL dllmap for
Mac OS X (thanks chrisse27).
2009-12-14 the_fiddler
* Source/OpenTK/Graphics/OpenGL/GLHelper.cs: * GLHelper.cs: Fixed
StackOverflowException in TexCoordPointer overload. (Issue
[#1444]: "TexCoordPointer creates StackOverflow").
2009-12-09 the_fiddler
* Source/Examples/OpenGLES/1.1/SimpleWindow.cs,
Source/Examples/OpenGLES/2.0/SimpleWindow20.cs: ClearColor takes
a clamped float in the range 0.0-1.0, instead of a byte argument.
* Source/OpenTK/Platform/EmbeddedGraphicsContext.cs: Do not attempt
to load ES10 and ES11 entry points, as these are disabled in
1.0.0.
2009-12-06 the_fiddler
* Source/OpenTK/Audio/OpenAL/AL/AL.cs: Clarified documentation for
alGetListener3f parameters.
* Source/Bind/Specifications/GL2/enumext.spec,
Source/OpenTK/Graphics/OpenGL/GLEnums.cs: Added missing 3.1 core
PRIMITIVE_RESTART token. Fixes issue [#1422]: "Missing
EnableCap.PrimitiveRestart".
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Removed IME class
style. Fixes the alt-tab order issue, where NativeWindows would
always appear last in the tab order (issue [#1244]: "Alt+Tab
weirdness"). Removed VRedraw and HRedraw class styles (not
necessary, since we are not relying on WM_PAINT messages).
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Removed unused
code.
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Ensure window is
activated and focused when created.
* Source/OpenTK/GameWindow.cs,
Source/OpenTK/Platform/X11/X11GLContext.cs,
Source/OpenTK/Platform/X11/X11GLNative.cs: Do not call Dispose()
automatically on GameWindow.Close(). Ensure that Unload event is
raised before window destruction, Ensure that Render and
UpdateFrame events are not called once the shutdown sequence is
initiated.
* Source/OpenTK/Platform/Windows/API.cs,
Source/OpenTK/Platform/Windows/WinGLNative.cs: *
OpenTK/Platform/Windows/API.cs: added SetForegroundWindow
dllimport.
* OpenTK/Platform/Windows/WinGLNative.cs: Move window to the
foreground before entering fullscreen mode.
2009-11-25 the_fiddler
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Correctly reset
Visible state when changing WindowBorder. Fixes issue [#1418]:
"[OpenTK] Invisible window when changing from Fullscreen to
Normal WIndowState on Windows 7".
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Fixed build
breakage introduced in r2551.
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Removed stale
code.
* Source/OpenTK/Platform/Windows/WinGLNative.cs: Use
TrackMouseEvent function for generating MouseEnter/MouseLeave
events. Resolves issues associated with SetCapture and windows
focus (bug [#1419]: "[OpenTK] NativeWindow reported as focused
whenever mouse enters its area, even without clicking (win32)").
* Source/OpenTK/Platform/X11/X11GLNative.cs: * X11GLNative.cs: Only
raise WindowStateChanged when the relevant PropertyNotify event
arrives. Fixes issue [#966]: "[GameWindow] Changing WindowBorder
from Hidden to Normal/Fixed does not update the relevant property
on KDE4.2".
* Source/Examples/OpenGL/1.1/VertexArrays.cs,
Source/Examples/OpenGL/1.1/VertexLighting.cs,
Source/Examples/OpenGL/GLSL/SimpleGLSL.cs,
Source/Examples/OpenTK/GameWindow/FullscreenAntialias.cs,
Source/Examples/OpenTK/GameWindow/SimpleWindow.cs,
Source/Examples/OpenTK/Test/Multithreading.cs,
Source/Examples/Utilities.cs: Normalized keyboard handling to use
F11 for fullscreen/normal switches.
2009-11-23 kanato
* Source/OpenTK/Platform/MacOS/AglContext.cs: MacOS: Fix context
sharing.
* Source/OpenTK/GameWindow.cs, Source/OpenTK/NativeWindow.cs,
Source/OpenTK/Platform/MacOS/AglContext.cs,
Source/OpenTK/Platform/MacOS/CarbonGLNative.cs,
Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs: MacOS:
Implement CarbonWindowInfo hack for going fullscreen.
--------------------------------- ---------------------------------
OpenTK 1.0 beta-1 -> 1.0 beta-2 OpenTK 1.0 beta-1 -> 1.0 beta-2
--------------------------------- ---------------------------------

View file

@ -1,6 +1,6 @@
The Open Toolkit library license The Open Toolkit library license
Copyright (c) 2006 - 2009 The Open Toolkit library. Copyright (c) 2006 - 2010 The Open Toolkit library.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View file

@ -1,18 +1,19 @@
The Open Toolkit 1.0 beta 2 The Open Toolkit 1.0 beta 3
[Overview] [Overview]
This is the second beta release of OpenTK 1.0. This release a laarge number of issues identified in the first beta. Additionally, it: This is the third beta release of OpenTK 1.0. This release resolves a large number of identified issues:
* improves support for Mac OS × (multiple monitors, dock integration, input focus and more). * adds support for doxygen-based documentation.
* allows OpenTK to run on *BSD, Solaris and other Unix variants. * significantly improves GameWindow stability.
* fixes a timing issue that caused UpdateFrame events to be raised up to 50% faster than necessary. * improves stability on multithreaded scenarios.
* adds a number of missing tokens for OpenGL 3.1 and 3.2. * fixes a number of input-related bugs.
* fixes mouse movement on windows and adds support for fractional wheel values (available in high-precision mice). * improves support for OpenGL 3.2 functions and adds a number of missing OpenGL tokens.
* fixes and optimizes quaternion-vector transforms. * features a better "GameWindow States" sample and introduces a "Multithreaded Rendering" sample.
* further improves multithreading support on Linux. * adds new double-precision based OpenGL overloads.
* works around a Visual Studio bug, which caused a number of OpenGL wrappers to disappear from intellisense. * fixes a number of smaller annoyances and oversights.
Visit http://www.opentk.com for the latest news and information on the Open Toolkit. Visit http://www.opentk.com for the latest news and information on the Open Toolkit.
@ -20,23 +21,32 @@ Visit http://www.opentk.com for the latest news and information on the Open Tool
[Resolved issues] [Resolved issues]
[#805] [#966]
[#1098] [#1244]
[#1162] [#1343]
[#1166] [#1417]
[#1216] [#1418]
[#1279] [#1419]
[#1324] [#1422]
[#1354] [#1443]
[#1355] [#1444]
[#1364] [#1446]
[#1367] [#1457]
[#1372] [#1467]
[#1373] [#1468]
[#1376] [#1483]
[#1378] [#1492]
[#1382] [#1498]
[#1386] [#1504]
[#1508]
[#1531]
[#1538]
[#1542]
[#1593]
[#1596]
[#1598]
[#1600]
Please report any issues you encounter at http://www.opentk.com/node/add/project-issue/opentk Please report any issues you encounter at http://www.opentk.com/node/add/project-issue/opentk
@ -44,16 +54,17 @@ Please report any issues you encounter at http://www.opentk.com/node/add/project
[Known issues] [Known issues]
* The Mac OS X port needs testing. If you encounter a bug, please report it at http://www.opentk.com/node/add/project-issue/opentk. * The Mac OS X port needs more testing. If you encounter a bug, please report it at http://www.opentk.com/node/add/project-issue/opentk.
* OpenGL 3.1 and 3.2 fucntions may be missing specific tokens. Please report any such issues at http://www.opentk.com/node/add/project-issue/opentk * OpenGL 3.1 and 3.2 fucntions may be missing specific tokens. Please report any such issues at http://www.opentk.com/node/add/project-issue/opentk
* Mono 2.2 and 2.4.0 fail to compile OpenTK due to a compiler bug (https://bugzilla.novell.com/show_bug.cgi?id=488960). Please compile with Mono 2.0, 2.4.2+ or use the supplied binaries instead. * Mono 2.2 and 2.4.0 fail to compile OpenTK due to a compiler bug (https://bugzilla.novell.com/show_bug.cgi?id=488960). Please compile with Mono 2.0, 2.4.2+ or use the supplied binaries instead.
* The example browser is a work-in-progress. * The example browser should list summaries for available samples.
* MonoDevelop fails to sign assemblies (bugs https://bugzilla.novell.com/show_bug.cgi?id=484752 and https://bugzilla.novell.com/show_bug.cgi?id=537063). * MonoDevelop fails to sign assemblies (bugs https://bugzilla.novell.com/show_bug.cgi?id=484752 and https://bugzilla.novell.com/show_bug.cgi?id=537063).
* XBuild <= 2.6.1 fails to compile OpenTK. This issue has been upstream.
[API changes] [API changes]
@ -63,6 +74,11 @@ Please note that binary compatibility is not preserved between beta releases.
If you are upgrading from OpenTK 0.9.9-0 or earlier you can simplify the upgrade process by adding a reference to OpenTK.Compatibility.dll and OpenTK.GLControl.dll (if necessary). OpenTK.Compatibility contains code and APIs that have been deprecated and removed from the core library and supports applications written against the Tao framework (Tao.OpenGl, Tao.OpenAl and Tao.Platform.Windows.SimpleOpenGlControl). If you are upgrading from OpenTK 0.9.9-0 or earlier you can simplify the upgrade process by adding a reference to OpenTK.Compatibility.dll and OpenTK.GLControl.dll (if necessary). OpenTK.Compatibility contains code and APIs that have been deprecated and removed from the core library and supports applications written against the Tao framework (Tao.OpenGl, Tao.OpenAl and Tao.Platform.Windows.SimpleOpenGlControl).
[1.0 beta-3]
No API changes.
[1.0 beta-2] [1.0 beta-2]
1. NormalPointer(..., int) and FogCoordPointer(..., int) overloads no longer specify a 'size' argument. 1. NormalPointer(..., int) and FogCoordPointer(..., int) overloads no longer specify a 'size' argument.

View file

@ -1,5 +1,4 @@
[General] [General]
+ Split TextPrinter from the core OpenTK.
+ Change all public APIs to conform to the class library interface guidelines. + Change all public APIs to conform to the class library interface guidelines.
+ Revisit all classes and make sure IDisposable is correctly implemented. + Revisit all classes and make sure IDisposable is correctly implemented.
+ Remove System.Windows.Forms dependency. + Remove System.Windows.Forms dependency.

View file

@ -38,6 +38,7 @@ GLuint64, UInt64
# ARB_sync (introduced in 3.2) # ARB_sync (introduced in 3.2)
sync, IntPtr sync, IntPtr
GLsync, IntPtr
# Wgl types. # Wgl types.
PROC, IntPtr PROC, IntPtr

View file

@ -1,4 +1,4 @@
#region --- License --- #region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos /* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
* See license.txt for license info * See license.txt for license info
*/ */
@ -21,23 +21,27 @@ namespace OpenTK.Build
{ {
class Project class Project
{ {
static string RootPath = Directory.GetCurrentDirectory(); static readonly string RootPath = Directory.GetCurrentDirectory();
static string SourcePath = Path.Combine(RootPath, "Source"); static readonly string SourcePath = Path.Combine(RootPath, "Source");
static readonly string DocPath = Path.Combine(RootPath, "Documentation");
const string bindings = "Generator.Prebuild.xml"; const string bindings = "Generator.Prebuild.xml";
const string opentk = "OpenTK.Prebuild.xml"; const string opentk = "OpenTK.Prebuild.xml";
const string quickstart = "QuickStart.Prebuild.xml"; const string quickstart = "QuickStart.Prebuild.xml";
const string DoxyFile = "Doxyfile";
const string ReferenceFile = "Reference.pdf";
const string keyfile = "OpenTK.snk"; // Do not change const string KeyFile = "OpenTK.snk"; // Do not change
const string Usage = @"Usage: Build.exe target const string Usage = @"Usage: Build.exe target
target: one of vs, vs9, clean, distclean, help"; target: one of vs, vs9, doc, clean, distclean, help";
const string Help = Usage + @" const string Help = Usage + @"
Available targets: Available targets:
vs: Create Visual Studio 2005 project files. vs: Create Visual Studio 2005 project files.
vs9: Create Visual Studio 2008 project files. vs9: Create Visual Studio 2008 project files.
doc: Builds html and pdf documentation.
clean: Delete intermediate files but leave final binaries and project clean: Delete intermediate files but leave final binaries and project
files intact. files intact.
distclean: Delete intermediate files, final binaries and project files. distclean: Delete intermediate files, final binaries and project files.
@ -60,6 +64,7 @@ Assembly signing:
Net, Net,
Clean, Clean,
DistClean, DistClean,
Docs,
} }
static void PrintUsage() static void PrintUsage()
@ -87,7 +92,7 @@ Assembly signing:
try try
{ {
PreparePrebuildFiles(); PrepareBuildFiles();
PrepareEnvironment(); PrepareEnvironment();
BuildTarget target = SelectTarget(args); BuildTarget target = SelectTarget(args);
@ -102,7 +107,7 @@ Assembly signing:
{ {
// Wait until Prebuild releases the input files. // Wait until Prebuild releases the input files.
System.Threading.Thread.Sleep(2000); System.Threading.Thread.Sleep(2000);
DeletePrebuildFiles(); DeleteBuildFiles();
} }
WaitForExit(); WaitForExit();
@ -115,16 +120,26 @@ Assembly signing:
Environment.SetEnvironmentVariable("ProgramFiles(x86)", String.Empty, EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("ProgramFiles(x86)", String.Empty, EnvironmentVariableTarget.Process);
} }
private static void PreparePrebuildFiles() private static void PrepareBuildFiles()
{ {
//string sign_assembly = CheckKeyFile(keyfile) ? "SIGN_ASSEMBLY" : ""; //string sign_assembly = CheckKeyFile(keyfile) ? "SIGN_ASSEMBLY" : "";
string sign_assembly = CheckKeyFile(keyfile) ? @"<KeyFile>" + keyfile + @"</KeyFile>" : ""; string sign_assembly = CheckKeyFile(KeyFile) ? @"<KeyFile>" + KeyFile + @"</KeyFile>" : "";
if (sign_assembly != "") if (sign_assembly != "")
DistributeKeyFile(keyfile); DistributeKeyFile(KeyFile);
File.WriteAllText(bindings, String.Format(Resources.Generator, sign_assembly)); File.WriteAllText(bindings, String.Format(Resources.Generator, sign_assembly));
File.WriteAllText(opentk, String.Format(Resources.OpenTK, sign_assembly)); File.WriteAllText(opentk, String.Format(Resources.OpenTK, sign_assembly));
File.WriteAllText(quickstart, String.Format(Resources.QuickStart, sign_assembly)); File.WriteAllText(quickstart, String.Format(Resources.QuickStart, sign_assembly));
string doxy = Regex.Replace(Resources.DoxyFile, @"(\{\}|\{\w+\})", "");
File.WriteAllText(DoxyFile, String.Format(doxy, GetVersion()));
}
// Returns the version of the executing assembly.
static string GetVersion()
{
string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
return version;
} }
// Copies keyfile to the various source directories. This is necessary // Copies keyfile to the various source directories. This is necessary
@ -174,6 +189,11 @@ Assembly signing:
target = BuildTarget.VS2008; target = BuildTarget.VS2008;
break; break;
case "doc":
case "docs":
target = BuildTarget.Docs;
break;
case "clean": case "clean":
target = BuildTarget.Clean; target = BuildTarget.Clean;
break; break;
@ -230,13 +250,40 @@ Assembly signing:
ExecutePrebuild("/target", "vs2008", "/file", quickstart); ExecutePrebuild("/target", "vs2008", "/file", quickstart);
break; break;
case BuildTarget.Docs:
Console.WriteLine("Generating reference documentation (this may take several minutes)...");
Console.WriteLine("Generating html sources...");
try { ExecuteCommand("doxygen", null, null); }
catch
{
Console.WriteLine("Failed to run \"doxygen\".");
Console.WriteLine("Please consult the documentation for more information.");
}
string latex_path = Path.Combine(Path.Combine(DocPath, "Source"), "latex");
Console.WriteLine("Compiling sources to pdf...");
try
{
ExecuteCommand("pdflatex", latex_path, "-interaction=batchmode", "refman.tex");
ExecuteCommand("makeindex", latex_path, "-q", "refman.idx");
ExecuteCommand("pdflatex", latex_path, "-interaction=batchmode", "refman.tex");
}
catch
{
Console.WriteLine("Failed to run \"pdflatex\" or \"makeindex\".");
Console.WriteLine("Please consult the documentation for more information");
}
File.Copy(Path.Combine(latex_path, "refman.pdf"),
Path.Combine(DocPath, ReferenceFile), true);
break;
case BuildTarget.Clean: case BuildTarget.Clean:
Console.WriteLine("Cleaning intermediate object files."); Console.WriteLine("Cleaning intermediate object files.");
ExecutePrebuild("/clean", "/yes", "/file", bindings); ExecutePrebuild("/clean", "/yes", "/file", bindings);
ExecutePrebuild("/clean", "/yes", "/file", opentk); ExecutePrebuild("/clean", "/yes", "/file", opentk);
ExecutePrebuild("/clean", "/yes", "/file", quickstart); ExecutePrebuild("/clean", "/yes", "/file", quickstart);
DeleteDirectories(RootPath, "obj"); DeleteDirectories(RootPath, "obj");
DeleteFiles(SourcePath, keyfile); DeleteFiles(SourcePath, KeyFile);
break; break;
case BuildTarget.DistClean: case BuildTarget.DistClean:
@ -246,11 +293,21 @@ Assembly signing:
ExecutePrebuild("/clean", "/yes", "/file", quickstart); ExecutePrebuild("/clean", "/yes", "/file", quickstart);
DeleteDirectories(RootPath, "obj"); DeleteDirectories(RootPath, "obj");
DeleteDirectories(RootPath, "bin"); DeleteDirectories(RootPath, "bin");
DeleteFiles(SourcePath, keyfile); DeleteDirectories(DocPath, "Source");
DeleteFiles(DocPath, ReferenceFile);
DeleteFiles(SourcePath, KeyFile);
string binaries_path = Path.Combine(RootPath, "Binaries"); string binaries_path = Path.Combine(RootPath, "Binaries");
if (Directory.Exists(binaries_path)) try
Directory.Delete(binaries_path, true); {
if (Directory.Exists(binaries_path))
Directory.Delete(binaries_path, true);
}
catch (Exception e)
{
Console.WriteLine("Failed to delete directory \"{0}\".", binaries_path);
Console.WriteLine(e.ToString());
}
break; break;
@ -265,18 +322,20 @@ Assembly signing:
{ {
if (Debugger.IsAttached) if (Debugger.IsAttached)
{ {
Console.WriteLine();
Console.WriteLine("Press any key to continue..."); Console.WriteLine("Press any key to continue...");
Console.ReadKey(true); Console.ReadKey(true);
} }
} }
static void DeletePrebuildFiles() static void DeleteBuildFiles()
{ {
try try
{ {
File.Delete(bindings); File.Delete(bindings);
File.Delete(opentk); File.Delete(opentk);
File.Delete(quickstart); File.Delete(quickstart);
File.Delete(DoxyFile);
} }
catch (IOException e) catch (IOException e)
{ {
@ -296,9 +355,7 @@ Assembly signing:
static void DeleteDirectories(string root_path, string search) static void DeleteDirectories(string root_path, string search)
{ {
Console.WriteLine("Deleting {0} directories", search); Console.WriteLine("Deleting {0} directories", search);
List<string> matches = new List<string>(); foreach (string m in Directory.GetDirectories(root_path, search, SearchOption.AllDirectories))
FindDirectories(root_path, search, matches);
foreach (string m in matches)
{ {
Directory.Delete(m, true); Directory.Delete(m, true);
} }
@ -307,9 +364,7 @@ Assembly signing:
static void DeleteFiles(string root_path, string search) static void DeleteFiles(string root_path, string search)
{ {
Console.WriteLine("Deleting {0} files", search); Console.WriteLine("Deleting {0} files", search);
List<string> matches = new List<string>(); foreach (string m in Directory.GetFiles(root_path, search, SearchOption.AllDirectories))
FindDirectories(root_path, search, matches);
foreach (string m in matches)
{ {
File.Delete(m); File.Delete(m);
} }
@ -386,6 +441,31 @@ Assembly signing:
Prebuild.EntryPoint.Invoke(null, new object[] { options }); Prebuild.EntryPoint.Invoke(null, new object[] { options });
} }
static void ExecuteCommand(string command, string workingDirectory, params string[] options)
{
ProcessStartInfo psi = new ProcessStartInfo(command);
if (options != null)
{
StringBuilder sb = new StringBuilder();
foreach (string opt in options)
{
sb.Append(opt);
sb.Append(" ");
}
psi.Arguments = sb.ToString();
}
if (!String.IsNullOrEmpty(workingDirectory))
{
psi.WorkingDirectory = workingDirectory;
psi.UseShellExecute = false;
}
Process p = Process.Start(psi);
p.WaitForExit();
}
static bool CheckKeyFile(string keyfile) static bool CheckKeyFile(string keyfile)
{ {
if (!File.Exists(keyfile)) if (!File.Exists(keyfile))

View file

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:2.0.50727.4918 // Runtime Version:2.0.50727.4927
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@ -60,6 +60,28 @@ namespace OpenTK.Build.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to # Doxyfile 1.6.1
///
///# This file describes the settings to be used by the documentation system
///# doxygen (www.doxygen.org) for a project
///#
///# All text after a hash (#) is considered a comment and will be ignored
///# The format is:
///# TAG = value [value, ...]
///# For lists items can also be appended using:
///# TAG += value [value, ...]
///# Values that contain spaces should be placed between quotes (&quot; &quot;)
///
///#---------------------------------------------------------------------------
///# Project relate [rest of string was truncated]&quot;;.
/// </summary>
internal static string DoxyFile {
get {
return ResourceManager.GetString("DoxyFile", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; /// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
///&lt;Prebuild xmlns=&quot;http://dnpb.sourceforge.net/schemas/prebuild-1.7.xsd&quot;&gt; ///&lt;Prebuild xmlns=&quot;http://dnpb.sourceforge.net/schemas/prebuild-1.7.xsd&quot;&gt;
@ -96,13 +118,13 @@ namespace OpenTK.Build.Properties {
/// &lt;CompilerDefines&gt;DEBUG;TRACE;&lt;/CompilerDefines&gt; /// &lt;CompilerDefines&gt;DEBUG;TRACE;&lt;/CompilerDefines&gt;
/// &lt;OptimizeCode&gt;false&lt;/OptimizeCode&gt; /// &lt;OptimizeCode&gt;false&lt;/OptimizeCode&gt;
/// &lt;DebugInformation&gt;true&lt;/DebugInformation&gt; /// &lt;DebugInformation&gt;true&lt;/DebugInformation&gt;
/// {0} &lt;!-- KeyFile --&gt;
/// &lt;/Options&gt; /// &lt;/Options&gt;
/// &lt;/Configuration&gt; /// &lt;/Configuration&gt;
/// ///
/// &lt;Configuration name=&quot;Release&quot;&gt; /// &lt;Configuration name=&quot;Release&quot;&gt;
/// &lt;Options&gt; /// &lt;Options&gt;
/// &lt;CompilerDefines&gt;TRACE;&lt;/CompilerDefines&gt; /// &lt;CompilerDefines&gt;TRACE;&lt;/Compi [rest of string was truncated]&quot;;.
/// &lt;Optimize [rest of string was truncated]&quot;;.
/// </summary> /// </summary>
internal static string OpenTK { internal static string OpenTK {
get { get {

View file

@ -118,6 +118,9 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="DoxyFile" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\DoxyFile.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;windows-1253</value>
</data>
<data name="Generator" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="Generator" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Generator.Prebuild.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> <value>..\Resources\Generator.Prebuild.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data> </data>

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,31 @@
using System; #region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2010 the Open Toolkit library, except where noted.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;

View file

@ -31,24 +31,6 @@ namespace Examples.Tutorial
struct Vbo { public int VboID, EboID, NumElements; } struct Vbo { public int VboID, EboID, NumElements; }
Vbo[] vbo = new Vbo[2]; Vbo[] vbo = new Vbo[2];
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct VertexPositionColor
{
public Vector3 Position;
public uint Color;
public VertexPositionColor(float x, float y, float z, Color color)
{
Position = new Vector3(x, y, z);
Color = ToRgba(color);
}
static uint ToRgba(Color color)
{
return (uint)color.A << 24 | (uint)color.B << 16 | (uint)color.G << 8 | (uint)color.R;
}
}
VertexPositionColor[] CubeVertices = new VertexPositionColor[] VertexPositionColor[] CubeVertices = new VertexPositionColor[]
{ {
new VertexPositionColor(-1.0f, -1.0f, 1.0f, Color.DarkRed), new VertexPositionColor(-1.0f, -1.0f, 1.0f, Color.DarkRed),

View file

@ -0,0 +1,275 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2010 the Open Toolkit library, except where noted.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
namespace Examples.Tutorial
{
/// <summary>
/// Demonstrates how to decouple rendering from the main thread.
/// Note that all OpenGL function calls should take place at the rendering thread -
/// OpenGL will not be available on the main thread at all!
/// </summary>
[Example("Threaded Rendering", ExampleCategory.OpenTK, "GameWindow", Documentation = "ThreadedRendering")]
public class ThreadedRendering : GameWindow
{
bool viewport_changed = true;
int viewport_width, viewport_height;
bool exit = false;
Thread rendering_thread;
object update_lock = new object();
const float rotation_speed = 180.0f;
float angle;
float aspect_ratio;
readonly VertexPositionColor[] CubeVertices = new VertexPositionColor[]
{
new VertexPositionColor(-1.0f, -1.0f, 1.0f, Color.DarkRed),
new VertexPositionColor( 1.0f, -1.0f, 1.0f, Color.DarkRed),
new VertexPositionColor( 1.0f, 1.0f, 1.0f, Color.Gold),
new VertexPositionColor(-1.0f, 1.0f, 1.0f, Color.Gold),
new VertexPositionColor(-1.0f, -1.0f, -1.0f, Color.DarkRed),
new VertexPositionColor( 1.0f, -1.0f, -1.0f, Color.DarkRed),
new VertexPositionColor( 1.0f, 1.0f, -1.0f, Color.Gold),
new VertexPositionColor(-1.0f, 1.0f, -1.0f, Color.Gold)
};
readonly short[] CubeElements = new short[]
{
0, 1, 2, 2, 3, 0, // front face
3, 2, 6, 6, 7, 3, // top face
7, 6, 5, 5, 4, 7, // back face
4, 0, 3, 3, 7, 4, // left face
0, 1, 5, 5, 4, 0, // bottom face
1, 5, 6, 6, 2, 1, // right face
};
public ThreadedRendering()
: base(800, 600)
{
Keyboard.KeyDown += Keyboard_KeyDown;
}
#region Keyboard_KeyDown
/// <summary>
/// Occurs when a key is pressed.
/// </summary>
/// <param name="sender">The KeyboardDevice which generated this event.</param>
/// <param name="e">The key that was pressed.</param>
void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e)
{
if (e.Key == Key.Escape)
this.Exit();
if (e.Key == Key.F11)
if (this.WindowState == WindowState.Fullscreen)
this.WindowState = WindowState.Normal;
else
this.WindowState = WindowState.Fullscreen;
}
#endregion
#region OnLoad
/// <summary>
/// Setup OpenGL and load resources here.
/// </summary>
/// <param name="e">Not used.</param>
protected override void OnLoad(EventArgs e)
{
Context.MakeCurrent(null); // Release the OpenGL context so it can be used on the new thread.
rendering_thread = new Thread(RenderLoop);
rendering_thread.IsBackground = true;
rendering_thread.Start();
}
#endregion
#region OnUnload
/// <summary>
/// Release resources here.
/// </summary>
/// <param name="e">Not used.</param>
protected override void OnUnload(EventArgs e)
{
exit = true; // Set a flag that the rendering thread should stop running.
rendering_thread.Join();
base.OnUnload(e);
}
#endregion
#region OnResize
/// <summary>
/// Respond to resize events here.
/// </summary>
/// <param name="e">Contains information on the new GameWindow size.</param>
/// <remarks>There is no need to call the base implementation.</remarks>
protected override void OnResize(EventArgs e)
{
// Note that we cannot call any OpenGL methods directly. What we can do is set
// a flag and respond to it from the rendering thread.
lock (update_lock)
{
viewport_changed = true;
viewport_width = Width;
viewport_height = Height;
}
}
#endregion
#region OnUpdateFrame
/// <summary>
/// Add your game logic here.
/// </summary>
/// <param name="e">Contains timing information.</param>
/// <remarks>There is no need to call the base implementation.</remarks>
protected override void OnUpdateFrame(FrameEventArgs e)
{
// Nothing to do!
}
#endregion
#region OnRenderFrame
/// <summary>
/// Ignored. All rendering is performed on our own rendering function.
/// </summary>
/// <param name="e">Contains timing information.</param>
/// <remarks>There is no need to call the base implementation.</remarks>
protected override void OnRenderFrame(FrameEventArgs e)
{
}
#endregion
#region RenderLoop
void RenderLoop()
{
MakeCurrent(); // The context now belongs to this thread. No other thread may use it!
VSync = VSyncMode.On;
// Since we don't use OpenTK's timing mechanism, we need to keep time ourselves;
Stopwatch watch = new Stopwatch();
watch.Start();
GL.ClearColor(Color.MidnightBlue);
GL.Enable(EnableCap.DepthTest);
while (!exit)
{
Render(watch.Elapsed.TotalSeconds);
watch.Reset(); // Stopwatch may be inaccurate over larger intervals.
watch.Start(); // Plus, timekeeping is easier if we always start counting from 0.
SwapBuffers();
}
}
#endregion
#region Render
/// <summary>
/// This is our main rendering function, which executes on the rendering thread.
/// </summary>
public void Render(double time)
{
lock (update_lock)
{
if (viewport_changed)
{
GL.Viewport(0, 0, viewport_width, viewport_height);
aspect_ratio = viewport_width / (float)viewport_height;
viewport_changed = false;
}
}
Matrix4 perspective =
Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspect_ratio, 1, 64);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref perspective);
Matrix4 lookat = Matrix4.LookAt(0, 5, 5, 0, 0, 0, 0, 1, 0);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref lookat);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
angle += rotation_speed * (float)time;
GL.Rotate(angle, 0.0f, 1.0f, 0.0f);
GL.Begin(BeginMode.Triangles);
for (int i = 0; i < CubeElements.Length; i++)
{
int element = CubeElements[i];
uint color = CubeVertices[element].Color;
GL.Color4((byte)(color), (byte)(color >> 8), (byte)(color >> 16), (byte)(color >> 24));
GL.Vertex3(CubeVertices[element].Position);
}
GL.End();
}
#endregion
#region public static void Main()
/// <summary>
/// Entry point of this example.
/// </summary>
[STAThread]
public static void Main()
{
using (GameWindow example = new ThreadedRendering())
{
// Get the title and category of this example using reflection.
Utilities.SetWindowTitle(example);
example.Run(30.0, 0.0);
}
}
#endregion
}
}

View file

@ -17,28 +17,34 @@ using OpenTK.Input;
namespace Examples.Tests namespace Examples.Tests
{ {
[Example("GameWindow states", ExampleCategory.OpenTK, "Test", Documentation="GameWindowStates")] [Example("GameWindow states", ExampleCategory.OpenTK, "Test", Documentation = "GameWindowStates")]
public class GameWindowStates : GameWindow public class GameWindowStates : GameWindow
{ {
readonly Font TextFont = new Font(FontFamily.GenericSansSerif, 16); static readonly Font TextFont = new Font(FontFamily.GenericSansSerif, 12);
readonly Bitmap TextBitmap = new Bitmap(1024, 256); Bitmap TextBitmap = new Bitmap(512, 512);
int texture; int texture;
bool mouse_in_window = false; bool mouse_in_window = false;
bool viewport_changed = true;
bool refresh_text = true;
public GameWindowStates() public GameWindowStates()
: base(800, 600) : base(800, 600)
{ {
VSync = VSyncMode.On; VSync = VSyncMode.On;
Keyboard.KeyUp += KeyUpHandler; Keyboard.KeyRepeat = true;
Keyboard.KeyDown += KeyDownHandler;
WindowBorderChanged += delegate(object sender, EventArgs e) { UpdateText(); };
WindowStateChanged += delegate(object sender, EventArgs e) { UpdateText(); }; MouseEnter += delegate { mouse_in_window = true; };
FocusedChanged += delegate(object sender, EventArgs e) { UpdateText(); }; MouseLeave += delegate { mouse_in_window = false; };
MouseEnter += delegate(object sender, EventArgs e) { mouse_in_window = true; UpdateText(); };
MouseLeave += delegate(object sender, EventArgs e) { mouse_in_window = false; UpdateText(); }; Move += delegate { refresh_text = true; };
Resize += delegate { refresh_text = true; };
WindowBorderChanged += delegate { refresh_text = true; };
WindowStateChanged += delegate { refresh_text = true; };
Mouse.Move += delegate { refresh_text = true; };
} }
void KeyUpHandler(object sender, KeyboardKeyEventArgs e) void KeyDownHandler(object sender, KeyboardKeyEventArgs e)
{ {
switch (e.Key) switch (e.Key)
{ {
@ -52,60 +58,100 @@ namespace Examples.Tests
case Key.Number5: WindowBorder = WindowBorder.Resizable; break; case Key.Number5: WindowBorder = WindowBorder.Resizable; break;
case Key.Number6: WindowBorder = WindowBorder.Fixed; break; case Key.Number6: WindowBorder = WindowBorder.Fixed; break;
case Key.Number7: WindowBorder = WindowBorder.Hidden; break; case Key.Number7: WindowBorder = WindowBorder.Hidden; break;
case Key.Left: X = X - 16; break;
case Key.Right: X = X + 16; break;
case Key.Up: Y = Y - 16; break;
case Key.Down: Y = Y + 16; break;
case Key.KeypadPlus:
case Key.Plus: Size += new Size(16, 16); break;
case Key.KeypadMinus:
case Key.Minus: Size -= new Size(16, 16); break;
} }
} }
void UpdateText() static int Clamp(int val, int min, int max)
{ {
using (Graphics gfx = Graphics.FromImage(TextBitmap)) return val > max ? max : val < min ? min : val;
{ }
gfx.Clear(Color.MidnightBlue);
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; static void DrawString(Graphics gfx, string str, int line)
{
gfx.DrawString(str, TextFont, Brushes.White, new PointF(0, line * TextFont.Height));
}
gfx.DrawString(String.Format("[1 - 4]: change WindowState (current: {0}).", this.WindowState), TextFont, Brushes.White, new PointF(0, 0)); protected override void OnUpdateFrame(FrameEventArgs e)
gfx.DrawString(String.Format("[5 - 7]: change WindowBorder (current: {0}).", this.WindowBorder), TextFont, Brushes.White, new PointF(0, TextFont.Height)); {
gfx.DrawString(String.Format("Focused: {0}.", this.Focused), TextFont, Brushes.White, new PointF(0, 2 * TextFont.Height)); if (refresh_text)
gfx.DrawString(String.Format("Mouse {0} window.", mouse_in_window ? "inside" : "outside of"), TextFont, Brushes.White, new PointF(0, 3 * TextFont.Height)); {
refresh_text = false;
using (Graphics gfx = Graphics.FromImage(TextBitmap))
{
int line = 0;
gfx.Clear(Color.MidnightBlue);
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
DrawString(gfx, String.Format("[1 - 4]: change WindowState (current: {0}).", this.WindowState), line++);
DrawString(gfx, String.Format("[5 - 7]: change WindowBorder (current: {0}).", this.WindowBorder), line++);
DrawString(gfx, String.Format("Focused: {0}.", this.Focused), line++);
DrawString(gfx, String.Format("Mouse {0} window.", mouse_in_window ? "inside" : "outside of"), line++);
DrawString(gfx, String.Format("Mouse position: {0}", new Vector3(Mouse.X, Mouse.Y, Mouse.Wheel)), line++);
DrawString(gfx, String.Format("Window.Bounds: {0}", Bounds), line++);
DrawString(gfx, String.Format("Window.Location: {0}, Size: {1}", Location, Size), line++);
DrawString(gfx, String.Format("Window.{{X={0}, Y={1}, Width={2}, Height={3}}}", X, Y, Width, Height), line++);
DrawString(gfx, String.Format("Window.ClientRectangle: {0}", ClientRectangle), line++);
}
} }
System.Drawing.Imaging.BitmapData data = TextBitmap.LockBits(new System.Drawing.Rectangle(0, 0, TextBitmap.Width, TextBitmap.Height), System.Drawing.Imaging.BitmapData data = TextBitmap.LockBits(
new System.Drawing.Rectangle(0, 0, TextBitmap.Width, TextBitmap.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, TextBitmap.Width, TextBitmap.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, TextBitmap.Width, TextBitmap.Height, PixelFormat.Bgra,
PixelType.UnsignedByte, data.Scan0);
TextBitmap.UnlockBits(data); TextBitmap.UnlockBits(data);
} }
protected override void OnLoad(EventArgs e) protected override void OnLoad(EventArgs e)
{ {
base.OnLoad(e); base.OnLoad(e);
GL.ClearColor(Color.MidnightBlue); GL.ClearColor(Color.MidnightBlue);
GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Texture2D);
texture = GL.GenTexture(); texture = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, texture); GL.BindTexture(TextureTarget.Texture2D, texture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, TextBitmap.Width, TextBitmap.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, TextBitmap.Width, TextBitmap.Height,
0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Nearest);
// Make sure text is displayed when the application starts.
UpdateText();
} }
protected override void OnResize(EventArgs e) protected override void OnResize(EventArgs e)
{ {
base.OnResize(e); base.OnResize(e);
viewport_changed = true;
GL.Viewport(0, 0, Width, Height);
Matrix4 ortho_projection = Matrix4.CreateOrthographicOffCenter(0, Width, Height, 0, -1, 1);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref ortho_projection);
} }
protected override void OnRenderFrame(FrameEventArgs e) protected override void OnRenderFrame(FrameEventArgs e)
{ {
base.OnRenderFrame(e); base.OnRenderFrame(e);
if (viewport_changed)
{
viewport_changed = false;
GL.Viewport(0, 0, Width, Height);
Matrix4 ortho_projection = Matrix4.CreateOrthographicOffCenter(0, Width, Height, 0, -1, 1);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref ortho_projection);
}
GL.Clear(ClearBufferMask.ColorBufferBit); GL.Clear(ClearBufferMask.ColorBufferBit);
@ -119,7 +165,6 @@ namespace Examples.Tests
GL.End(); GL.End();
SwapBuffers(); SwapBuffers();
Thread.Sleep(5);
} }
public static void Main() public static void Main()
@ -127,7 +172,7 @@ namespace Examples.Tests
using (GameWindowStates ex = new GameWindowStates()) using (GameWindowStates ex = new GameWindowStates())
{ {
Utilities.SetWindowTitle(ex); Utilities.SetWindowTitle(ex);
ex.Run(20.0); ex.Run(30.0);
} }
} }
} }

View file

@ -0,0 +1,51 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2010 the Open Toolkit library, except where noted.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
using System.Drawing;
using System.Runtime.InteropServices;
using OpenTK;
namespace Examples.Tutorial
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct VertexPositionColor
{
public Vector3 Position;
public uint Color;
public VertexPositionColor(float x, float y, float z, Color color)
{
Position = new Vector3(x, y, z);
Color = ToRgba(color);
}
static uint ToRgba(Color color)
{
return (uint)color.A << 24 | (uint)color.B << 16 | (uint)color.G << 8 | (uint)color.R;
}
}
}

View file

@ -295,7 +295,7 @@ namespace OpenTK
/// <param name="e"> /// <param name="e">
/// The <see cref="System.ComponentModel.CancelEventArgs" /> for this event. /// The <see cref="System.ComponentModel.CancelEventArgs" /> for this event.
/// Set e.Cancel to true in order to stop the GameWindow from closing.</param> /// Set e.Cancel to true in order to stop the GameWindow from closing.</param>
protected override void OnClosing (System.ComponentModel.CancelEventArgs e) protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{ {
base.OnClosing(e); base.OnClosing(e);
if (!e.Cancel) if (!e.Cancel)
@ -392,6 +392,7 @@ namespace OpenTK
Visible = true; // Make sure the GameWindow is visible. Visible = true; // Make sure the GameWindow is visible.
OnLoadInternal(EventArgs.Empty); OnLoadInternal(EventArgs.Empty);
OnResize(EventArgs.Empty);
// On some platforms, ProcessEvents() does not return while the user is resizing or moving // On some platforms, ProcessEvents() does not return while the user is resizing or moving
// the window. We can avoid this issue by raising UpdateFrame and RenderFrame events // the window. We can avoid this issue by raising UpdateFrame and RenderFrame events
@ -510,7 +511,9 @@ namespace OpenTK
// rises again. // rises again.
// Note 2: calling Context.VSync = true repeatedly seems to cause jitter on // Note 2: calling Context.VSync = true repeatedly seems to cause jitter on
// some configurations. If possible, we should avoid repeated calls. // some configurations. If possible, we should avoid repeated calls.
if (VSync == VSyncMode.Adaptive && TargetRenderPeriod != 0) // Note 3: we may not read/write the VSync property without a current context.
// This may come to pass if the user has moved rendering to his own thread.
if (Context.IsCurrent && VSync == VSyncMode.Adaptive && TargetRenderPeriod != 0)
{ {
// Check if we have enough time for a vsync // Check if we have enough time for a vsync
if (RenderTime > 2.0 * TargetRenderPeriod) if (RenderTime > 2.0 * TargetRenderPeriod)
@ -896,33 +899,33 @@ namespace OpenTK
#endregion #endregion
#region WindowState #region WindowState
/// <summary> /// <summary>
/// Gets or states the state of the NativeWindow. /// Gets or states the state of the NativeWindow.
/// </summary> /// </summary>
public override WindowState WindowState public override WindowState WindowState
{ {
get get
{ {
return base.WindowState; return base.WindowState;
} }
set set
{ {
base.WindowState = value; base.WindowState = value;
Debug.Print("Updating Context after setting WindowState to {0}", value); Debug.Print("Updating Context after setting WindowState to {0}", value);
if (Context != null) if (Context != null)
Context.Update(WindowInfo); Context.Update(WindowInfo);
} }
} }
#endregion #endregion
#endregion #endregion
#region Events #region Events
/// <summary> /// <summary>
/// Occurs before the window is displayed for the first time. /// Occurs before the window is displayed for the first time.
/// </summary> /// </summary>
public event EventHandler<EventArgs> Load; public event EventHandler<EventArgs> Load;
@ -1000,25 +1003,24 @@ namespace OpenTK
#endregion #endregion
#region OnResize #region OnResize
protected override void OnResize(EventArgs e) protected override void OnResize(EventArgs e)
{ {
base.OnResize(e); base.OnResize(e);
glContext.Update(base.WindowInfo); glContext.Update(base.WindowInfo);
} }
#endregion #endregion
#endregion #endregion
#region --- Private Members --- #region --- Private Members ---
#region OnLoadInternal #region OnLoadInternal
private void OnLoadInternal(EventArgs e) private void OnLoadInternal(EventArgs e)
{ {
OnResize(EventArgs.Empty);
OnLoad(e); OnLoad(e);
} }

View file

@ -186,7 +186,7 @@ namespace OpenTK.Graphics.OpenGL
#endregion #endregion
#region --- Overloads for OpenTK.Math --- #region Normal|RasterPos|Vertex|TexCoord|Rotate|Scale|Translate|*Matrix
public static void Normal3(Vector3 normal) public static void Normal3(Vector3 normal)
{ {
@ -297,6 +297,82 @@ namespace OpenTK.Graphics.OpenGL
} }
} }
public static void UniformMatrix4(int location, bool transpose, ref Matrix4 matrix)
{
unsafe
{
fixed (float* matrix_ptr = &matrix.Row0.X)
{
GL.UniformMatrix4(location, 1, transpose, matrix_ptr);
}
}
}
public static void Normal3(Vector3d normal)
{
GL.Normal3(normal.X, normal.Y, normal.Z);
}
public static void RasterPos2(Vector2d pos)
{
GL.RasterPos2(pos.X, pos.Y);
}
public static void RasterPos3(Vector3d pos)
{
GL.RasterPos3(pos.X, pos.Y, pos.Z);
}
public static void RasterPos4(Vector4d pos)
{
GL.RasterPos4(pos.X, pos.Y, pos.Z, pos.W);
}
public static void Vertex2(Vector2d v)
{
GL.Vertex2(v.X, v.Y);
}
public static void Vertex3(Vector3d v)
{
GL.Vertex3(v.X, v.Y, v.Z);
}
public static void Vertex4(Vector4d v)
{
GL.Vertex4(v.X, v.Y, v.Z, v.W);
}
public static void TexCoord2(Vector2d v)
{
GL.TexCoord2(v.X, v.Y);
}
public static void TexCoord3(Vector3d v)
{
GL.TexCoord3(v.X, v.Y, v.Z);
}
public static void TexCoord4(Vector4d v)
{
GL.TexCoord4(v.X, v.Y, v.Z, v.W);
}
public static void Rotate(double angle, Vector3d axis)
{
GL.Rotate((double)angle, axis.X, axis.Y, axis.Z);
}
public static void Scale(Vector3d scale)
{
GL.Scale(scale.X, scale.Y, scale.Z);
}
public static void Translate(Vector3d trans)
{
GL.Translate(trans.X, trans.Y, trans.Z);
}
public static void MultMatrix(ref Matrix4d mat) public static void MultMatrix(ref Matrix4d mat)
{ {
unsafe unsafe
@ -341,17 +417,6 @@ namespace OpenTK.Graphics.OpenGL
} }
} }
public static void UniformMatrix4(int location, bool transpose, ref Matrix4 matrix)
{
unsafe
{
fixed (float* matrix_ptr = &matrix.Row0.X)
{
GL.UniformMatrix4(location, 1, transpose, matrix_ptr);
}
}
}
#region Uniform #region Uniform
[CLSCompliant(false)] [CLSCompliant(false)]
@ -553,7 +618,7 @@ namespace OpenTK.Graphics.OpenGL
#endregion #endregion
#region public static void VertexAttrib2(Int32 index, ref Vector2 v) #region VertexAttrib|MultiTexCoord
[CLSCompliant(false)] [CLSCompliant(false)]
public static void VertexAttrib2(Int32 index, ref Vector2 v) public static void VertexAttrib2(Int32 index, ref Vector2 v)
@ -561,92 +626,109 @@ namespace OpenTK.Graphics.OpenGL
GL.VertexAttrib2(index, v.X, v.Y); GL.VertexAttrib2(index, v.X, v.Y);
} }
#endregion
#region public static void VertexAttrib3(Int32 index, ref Vector3 v)
[CLSCompliant(false)] [CLSCompliant(false)]
public static void VertexAttrib3(Int32 index, ref Vector3 v) public static void VertexAttrib3(Int32 index, ref Vector3 v)
{ {
GL.VertexAttrib3(index, v.X, v.Y, v.Z); GL.VertexAttrib3(index, v.X, v.Y, v.Z);
} }
#endregion
#region public static void VertexAttrib4(Int32 index, ref Vector4 v)
[CLSCompliant(false)] [CLSCompliant(false)]
public static void VertexAttrib4(Int32 index, ref Vector4 v) public static void VertexAttrib4(Int32 index, ref Vector4 v)
{ {
GL.VertexAttrib4(index, v.X, v.Y, v.Z, v.W); GL.VertexAttrib4(index, v.X, v.Y, v.Z, v.W);
} }
#endregion
#region public static void VertexAttrib2(Int32 index, Vector2 v)
public static void VertexAttrib2(Int32 index, Vector2 v) public static void VertexAttrib2(Int32 index, Vector2 v)
{ {
GL.VertexAttrib2(index, v.X, v.Y); GL.VertexAttrib2(index, v.X, v.Y);
} }
#endregion
#region public static void VertexAttrib3(Int32 index, Vector3 v)
public static void VertexAttrib3(Int32 index, Vector3 v) public static void VertexAttrib3(Int32 index, Vector3 v)
{ {
GL.VertexAttrib3(index, v.X, v.Y, v.Z); GL.VertexAttrib3(index, v.X, v.Y, v.Z);
} }
#endregion
#region public static void VertexAttrib4(Int32 index, Vector4 v)
public static void VertexAttrib4(Int32 index, Vector4 v) public static void VertexAttrib4(Int32 index, Vector4 v)
{ {
GL.VertexAttrib4(index, v.X, v.Y, v.Z, v.W); GL.VertexAttrib4(index, v.X, v.Y, v.Z, v.W);
} }
#endregion
#region public static void MultiTexCoord2(TextureUnit target, ref Vector2 v)
public static void MultiTexCoord2(TextureUnit target, ref Vector2 v) public static void MultiTexCoord2(TextureUnit target, ref Vector2 v)
{ {
GL.MultiTexCoord2(target, v.X, v.Y); GL.MultiTexCoord2(target, v.X, v.Y);
} }
#endregion
#region public static void MultiTexCoord3(TextureUnit target, ref Vector3 v)
public static void MultiTexCoord3(TextureUnit target, ref Vector3 v) public static void MultiTexCoord3(TextureUnit target, ref Vector3 v)
{ {
GL.MultiTexCoord3(target, v.X, v.Y, v.Z); GL.MultiTexCoord3(target, v.X, v.Y, v.Z);
} }
#endregion
#region public static void MultiTexCoord4(TextureUnit target, ref Vector4 v)
public static void MultiTexCoord4(TextureUnit target, ref Vector4 v) public static void MultiTexCoord4(TextureUnit target, ref Vector4 v)
{ {
GL.MultiTexCoord4(target, v.X, v.Y, v.Z, v.W); GL.MultiTexCoord4(target, v.X, v.Y, v.Z, v.W);
} }
[CLSCompliant(false)]
public static void VertexAttrib2(Int32 index, ref Vector2d v)
{
GL.VertexAttrib2(index, v.X, v.Y);
}
[CLSCompliant(false)]
public static void VertexAttrib3(Int32 index, ref Vector3d v)
{
GL.VertexAttrib3(index, v.X, v.Y, v.Z);
}
[CLSCompliant(false)]
public static void VertexAttrib4(Int32 index, ref Vector4d v)
{
GL.VertexAttrib4(index, v.X, v.Y, v.Z, v.W);
}
public static void VertexAttrib2(Int32 index, Vector2d v)
{
GL.VertexAttrib2(index, v.X, v.Y);
}
public static void VertexAttrib3(Int32 index, Vector3d v)
{
GL.VertexAttrib3(index, v.X, v.Y, v.Z);
}
public static void VertexAttrib4(Int32 index, Vector4d v)
{
GL.VertexAttrib4(index, v.X, v.Y, v.Z, v.W);
}
public static void MultiTexCoord2(TextureUnit target, ref Vector2d v)
{
GL.MultiTexCoord2(target, v.X, v.Y);
}
public static void MultiTexCoord3(TextureUnit target, ref Vector3d v)
{
GL.MultiTexCoord3(target, v.X, v.Y, v.Z);
}
public static void MultiTexCoord4(TextureUnit target, ref Vector4d v)
{
GL.MultiTexCoord4(target, v.X, v.Y, v.Z, v.W);
}
#endregion #endregion
#region public static void Rect(System.Drawing.RectangleF rect) #region Rect
public static void Rect(System.Drawing.RectangleF rect) public static void Rect(System.Drawing.RectangleF rect)
{ {
GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom); GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
} }
#endregion public static void Rect(System.Drawing.Rectangle rect)
{
#region public static void Rect(ref System.Drawing.RectangleF rect) GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
[CLSCompliant(false)] [CLSCompliant(false)]
public static void Rect(ref System.Drawing.RectangleF rect) public static void Rect(ref System.Drawing.RectangleF rect)
@ -654,19 +736,6 @@ namespace OpenTK.Graphics.OpenGL
GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom); GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
} }
#endregion
#region public static void Rect(System.Drawing.Rectangle rect)
public static void Rect(System.Drawing.Rectangle rect)
{
GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
#endregion
#region public static void Rect(ref System.Drawing.Rectangle rect)
[CLSCompliant(false)] [CLSCompliant(false)]
public static void Rect(ref System.Drawing.Rectangle rect) public static void Rect(ref System.Drawing.Rectangle rect)
{ {

View file

@ -872,7 +872,7 @@ namespace OpenTK
protected void ProcessEvents(bool retainEvents) protected void ProcessEvents(bool retainEvents)
{ {
EnsureUndisposed(); EnsureUndisposed();
if (!events) Events = true; if (!retainEvents && !events) Events = true;
implementation.ProcessEvents(); implementation.ProcessEvents();
} }

View file

@ -13,6 +13,7 @@ using OpenTK.Graphics;
namespace OpenTK.Platform.Dummy namespace OpenTK.Platform.Dummy
{ {
/// \internal
/// <summary> /// <summary>
/// An empty IGraphicsContext implementation to be used inside the Visual Studio designer. /// An empty IGraphicsContext implementation to be used inside the Visual Studio designer.
/// This class supports OpenTK, and is not intended for use by OpenTK programs. /// This class supports OpenTK, and is not intended for use by OpenTK programs.

View file

@ -32,6 +32,7 @@ using System.Text;
namespace OpenTK.Platform.MacOS namespace OpenTK.Platform.MacOS
{ {
/// \internal
/// <summary> /// <summary>
/// Describes a Carbon window. /// Describes a Carbon window.
/// </summary> /// </summary>

View file

@ -70,6 +70,7 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
/// \internal
/// <summary> /// <summary>
/// For internal use by OpenTK only! /// For internal use by OpenTK only!
/// Exposes useful native WINAPI methods and structures. /// Exposes useful native WINAPI methods and structures.
@ -847,6 +848,9 @@ namespace OpenTK.Platform.Windows
[DllImport("user32.dll", SetLastError=true)] [DllImport("user32.dll", SetLastError=true)]
public static extern BOOL SetForegroundWindow(HWND hWnd); public static extern BOOL SetForegroundWindow(HWND hWnd);
[DllImport("user32.dll", SetLastError = true)]
public static extern BOOL BringWindowToTop(HWND hWnd);
#endregion #endregion
#region Display settings #region Display settings
@ -1679,6 +1683,7 @@ namespace OpenTK.Platform.Windows
#region PixelFormatDescriptor #region PixelFormatDescriptor
/// \internal
/// <summary> /// <summary>
/// Describes a pixel format. It is used when interfacing with the WINAPI to create a new Context. /// Describes a pixel format. It is used when interfacing with the WINAPI to create a new Context.
/// Found in WinGDI.h /// Found in WinGDI.h
@ -1718,6 +1723,7 @@ namespace OpenTK.Platform.Windows
#region internal class LayerPlaneDescriptor #region internal class LayerPlaneDescriptor
/// \internal
/// <summary> /// <summary>
/// Describes the pixel format of a drawing surface. /// Describes the pixel format of a drawing surface.
/// </summary> /// </summary>
@ -1754,6 +1760,7 @@ namespace OpenTK.Platform.Windows
#region GlyphMetricsFloat #region GlyphMetricsFloat
/// \internal
/// <summary> /// <summary>
/// The <b>GlyphMetricsFloat</b> structure contains information about the placement and orientation of a glyph in a /// The <b>GlyphMetricsFloat</b> structure contains information about the placement and orientation of a glyph in a
/// character cell. /// character cell.
@ -1789,6 +1796,7 @@ namespace OpenTK.Platform.Windows
#region PointFloat #region PointFloat
/// \internal
/// <summary> /// <summary>
/// The <b>PointFloat</b> structure contains the x and y coordinates of a point. /// The <b>PointFloat</b> structure contains the x and y coordinates of a point.
/// </summary> /// </summary>
@ -1917,7 +1925,8 @@ namespace OpenTK.Platform.Windows
#endregion DeviceMode class #endregion DeviceMode class
#region DisplayDevice #region DisplayDevice
/// \internal
/// <summary> /// <summary>
/// The DISPLAY_DEVICE structure receives information about the display device specified by the iDevNum parameter of the EnumDisplayDevices function. /// The DISPLAY_DEVICE structure receives information about the display device specified by the iDevNum parameter of the EnumDisplayDevices function.
/// </summary> /// </summary>
@ -1995,6 +2004,7 @@ namespace OpenTK.Platform.Windows
#region internal struct MinMaxInfo #region internal struct MinMaxInfo
/// \internal
/// <summary> /// <summary>
/// Struct pointed to by WM_GETMINMAXINFO lParam /// Struct pointed to by WM_GETMINMAXINFO lParam
/// </summary> /// </summary>
@ -2012,6 +2022,7 @@ namespace OpenTK.Platform.Windows
#region internal struct WindowPosition #region internal struct WindowPosition
/// \internal
/// <summary> /// <summary>
/// The WindowPosition structure contains information about the size and position of a window. /// The WindowPosition structure contains information about the size and position of a window.
/// </summary> /// </summary>
@ -2133,6 +2144,7 @@ namespace OpenTK.Platform.Windows
#region RawInputDevice #region RawInputDevice
/// \internal
/// <summary> /// <summary>
/// Defines information for the raw input devices. /// Defines information for the raw input devices.
/// </summary> /// </summary>
@ -2174,6 +2186,7 @@ namespace OpenTK.Platform.Windows
#region RawInputDeviceList #region RawInputDeviceList
/// \internal
/// <summary> /// <summary>
/// Contains information about a raw input device. /// Contains information about a raw input device.
/// </summary> /// </summary>
@ -2199,6 +2212,7 @@ namespace OpenTK.Platform.Windows
#region RawInput #region RawInput
/// \internal
/// <summary> /// <summary>
/// Contains the raw input from a device. /// Contains the raw input from a device.
/// </summary> /// </summary>
@ -2244,6 +2258,7 @@ namespace OpenTK.Platform.Windows
#region RawInputHeader #region RawInputHeader
/// \internal
/// <summary> /// <summary>
/// Contains the header information that is part of the raw input data. /// Contains the header information that is part of the raw input data.
/// </summary> /// </summary>
@ -2275,6 +2290,7 @@ namespace OpenTK.Platform.Windows
#region RawKeyboard #region RawKeyboard
/// \internal
/// <summary> /// <summary>
/// Contains information about the state of the keyboard. /// Contains information about the state of the keyboard.
/// </summary> /// </summary>
@ -2321,6 +2337,7 @@ namespace OpenTK.Platform.Windows
#region RawMouse #region RawMouse
/// \internal
/// <summary> /// <summary>
/// Contains information about the state of the mouse. /// Contains information about the state of the mouse.
/// </summary> /// </summary>
@ -2436,6 +2453,7 @@ namespace OpenTK.Platform.Windows
#region RawHID #region RawHID
/// \internal
/// <summary> /// <summary>
/// The RawHID structure describes the format of the raw input /// The RawHID structure describes the format of the raw input
/// from a Human Interface Device (HID). /// from a Human Interface Device (HID).
@ -2466,6 +2484,7 @@ namespace OpenTK.Platform.Windows
#region RawInputDeviceInfo #region RawInputDeviceInfo
/// \internal
/// <summary> /// <summary>
/// Defines the raw input data coming from any device. /// Defines the raw input data coming from any device.
/// </summary> /// </summary>
@ -2497,6 +2516,7 @@ namespace OpenTK.Platform.Windows
#region RawInputHIDDeviceInfo #region RawInputHIDDeviceInfo
/// \internal
/// <summary> /// <summary>
/// Defines the raw input data coming from the specified Human Interface Device (HID). /// Defines the raw input data coming from the specified Human Interface Device (HID).
/// </summary> /// </summary>
@ -2531,6 +2551,7 @@ namespace OpenTK.Platform.Windows
#region RawInputKeyboardDeviceInfo #region RawInputKeyboardDeviceInfo
/// \internal
/// <summary> /// <summary>
/// Defines the raw input data coming from the specified keyboard. /// Defines the raw input data coming from the specified keyboard.
/// </summary> /// </summary>
@ -2570,6 +2591,7 @@ namespace OpenTK.Platform.Windows
#region RawInputMouseDeviceInfo #region RawInputMouseDeviceInfo
/// \internal
/// <summary> /// <summary>
/// Defines the raw input data coming from the specified mouse. /// Defines the raw input data coming from the specified mouse.
/// </summary> /// </summary>
@ -2610,6 +2632,7 @@ namespace OpenTK.Platform.Windows
#region Rectangle #region Rectangle
/// \internal
/// <summary> /// <summary>
/// Defines the coordinates of the upper-left and lower-right corners of a rectangle. /// Defines the coordinates of the upper-left and lower-right corners of a rectangle.
/// </summary> /// </summary>
@ -2681,6 +2704,7 @@ namespace OpenTK.Platform.Windows
#region WindowInfo #region WindowInfo
/// \internal
/// <summary> /// <summary>
/// Contains window information. /// Contains window information.
/// </summary> /// </summary>
@ -3526,6 +3550,7 @@ namespace OpenTK.Platform.Windows
#region QueueStatusFlags #region QueueStatusFlags
/// \internal
/// <summary> /// <summary>
/// Queue status flags for GetQueueStatus() and MsgWaitForMultipleObjects() /// Queue status flags for GetQueueStatus() and MsgWaitForMultipleObjects()
/// </summary> /// </summary>

View file

@ -20,6 +20,7 @@ using OpenTK.Graphics.OpenGL;
namespace OpenTK.Platform.Windows namespace OpenTK.Platform.Windows
{ {
/// \internal
/// <summary> /// <summary>
/// Provides methods to create and control an opengl context on the Windows platform. /// Provides methods to create and control an opengl context on the Windows platform.
/// This class supports OpenTK, and is not intended for use by OpenTK programs. /// This class supports OpenTK, and is not intended for use by OpenTK programs.

View file

@ -37,6 +37,7 @@ using System.Drawing;
namespace OpenTK.Platform.Windows namespace OpenTK.Platform.Windows
{ {
/// \internal
/// <summary> /// <summary>
/// Drives GameWindow on Windows. /// Drives GameWindow on Windows.
/// This class supports OpenTK, and is not intended for use by OpenTK programs. /// This class supports OpenTK, and is not intended for use by OpenTK programs.
@ -45,15 +46,12 @@ namespace OpenTK.Platform.Windows
{ {
#region Fields #region Fields
readonly static object SyncRoot = new object();
const ExtendedWindowStyle ParentStyleEx = ExtendedWindowStyle.WindowEdge | ExtendedWindowStyle.ApplicationWindow; const ExtendedWindowStyle ParentStyleEx = ExtendedWindowStyle.WindowEdge | ExtendedWindowStyle.ApplicationWindow;
const ExtendedWindowStyle ChildStyleEx = 0; const ExtendedWindowStyle ChildStyleEx = 0;
readonly IntPtr Instance = Marshal.GetHINSTANCE(typeof(WinGLNative).Module); readonly IntPtr Instance = Marshal.GetHINSTANCE(typeof(WinGLNative).Module);
readonly IntPtr ClassName; readonly IntPtr ClassName = Marshal.StringToHGlobalAuto(Guid.NewGuid().ToString());
readonly WindowProcedure WindowProcedureDelegate; readonly WindowProcedure WindowProcedureDelegate;
readonly UIntPtr ModalLoopTimerId;
readonly uint ModalLoopTimerPeriod = 1; readonly uint ModalLoopTimerPeriod = 1;
UIntPtr timer_handle; UIntPtr timer_handle;
readonly Functions.TimerProc ModalLoopCallback; readonly Functions.TimerProc ModalLoopCallback;
@ -69,6 +67,8 @@ namespace OpenTK.Platform.Windows
bool borderless_maximized_window_state = false; // Hack to get maximized mode with hidden border (not normally possible). bool borderless_maximized_window_state = false; // Hack to get maximized mode with hidden border (not normally possible).
bool focused; bool focused;
bool mouse_outside_window = true; bool mouse_outside_window = true;
bool invisible_since_creation; // Set by WindowsMessage.CREATE and consumed by Visible = true (calls BringWindowToFront).
int suppress_resize; // Used in WindowBorder and WindowState in order to avoid rapid, consecutive resize events.
Rectangle Rectangle
bounds = new Rectangle(), bounds = new Rectangle(),
@ -93,21 +93,12 @@ namespace OpenTK.Platform.Windows
KeyPressEventArgs key_press = new KeyPressEventArgs((char)0); KeyPressEventArgs key_press = new KeyPressEventArgs((char)0);
static int window_count;
#endregion #endregion
#region Contructors #region Contructors
public WinGLNative(int x, int y, int width, int height, string title, GameWindowFlags options, DisplayDevice device) public WinGLNative(int x, int y, int width, int height, string title, GameWindowFlags options, DisplayDevice device)
{ {
lock (SyncRoot)
{
++window_count;
ClassName = Marshal.StringToHGlobalAuto(typeof(WinGLNative).Name + window_count.ToString());
ModalLoopTimerId = new UIntPtr((uint)window_count);
}
// This is the main window procedure callback. We need the callback in order to create the window, so // This is the main window procedure callback. We need the callback in order to create the window, so
// don't move it below the CreateWindow calls. // don't move it below the CreateWindow calls.
WindowProcedureDelegate = WindowProcedure; WindowProcedureDelegate = WindowProcedure;
@ -165,7 +156,7 @@ namespace OpenTK.Platform.Windows
if (new_focused_state != Focused && FocusedChanged != null) if (new_focused_state != Focused && FocusedChanged != null)
FocusedChanged(this, EventArgs.Empty); FocusedChanged(this, EventArgs.Empty);
return IntPtr.Zero; break;
case WindowMessage.ENTERMENULOOP: case WindowMessage.ENTERMENULOOP:
case WindowMessage.ENTERSIZEMOVE: case WindowMessage.ENTERSIZEMOVE:
@ -213,7 +204,7 @@ namespace OpenTK.Platform.Windows
SetWindowPosFlags.NOZORDER | SetWindowPosFlags.NOOWNERZORDER | SetWindowPosFlags.NOZORDER | SetWindowPosFlags.NOOWNERZORDER |
SetWindowPosFlags.NOACTIVATE | SetWindowPosFlags.NOSENDCHANGING); SetWindowPosFlags.NOACTIVATE | SetWindowPosFlags.NOSENDCHANGING);
if (Resize != null) if (suppress_resize <= 0 && Resize != null)
Resize(this, EventArgs.Empty); Resize(this, EventArgs.Empty);
} }
} }
@ -268,7 +259,7 @@ namespace OpenTK.Platform.Windows
key_press.KeyChar = (char)wParam.ToInt32(); key_press.KeyChar = (char)wParam.ToInt32();
else else
key_press.KeyChar = (char)wParam.ToInt64(); key_press.KeyChar = (char)wParam.ToInt64();
if (KeyPress != null) if (KeyPress != null)
KeyPress(this, key_press); KeyPress(this, key_press);
break; break;
@ -294,7 +285,7 @@ namespace OpenTK.Platform.Windows
case WindowMessage.MOUSELEAVE: case WindowMessage.MOUSELEAVE:
mouse_outside_window = true; mouse_outside_window = true;
// Mouse tracking is disabled automatically by the OS // Mouse tracking is disabled automatically by the OS
if (MouseLeave != null) if (MouseLeave != null)
MouseLeave(this, EventArgs.Empty); MouseLeave(this, EventArgs.Empty);
break; break;
@ -441,13 +432,13 @@ namespace OpenTK.Platform.Windows
Functions.GetClientRect(handle, out rect); Functions.GetClientRect(handle, out rect);
client_rectangle = rect.ToRectangle(); client_rectangle = rect.ToRectangle();
Functions.SetForegroundWindow(handle); invisible_since_creation = true;
} }
break; break;
case WindowMessage.CLOSE: case WindowMessage.CLOSE:
System.ComponentModel.CancelEventArgs e = new System.ComponentModel.CancelEventArgs(); System.ComponentModel.CancelEventArgs e = new System.ComponentModel.CancelEventArgs();
if (Closing != null) if (Closing != null)
Closing(this, e); Closing(this, e);
@ -471,7 +462,7 @@ namespace OpenTK.Platform.Windows
if (Closed != null) if (Closed != null)
Closed(this, EventArgs.Empty); Closed(this, EventArgs.Empty);
break; break;
#endregion #endregion
@ -496,7 +487,7 @@ namespace OpenTK.Platform.Windows
{ {
if (timer_handle == UIntPtr.Zero) if (timer_handle == UIntPtr.Zero)
{ {
timer_handle = Functions.SetTimer(handle, ModalLoopTimerId, ModalLoopTimerPeriod, ModalLoopCallback); timer_handle = Functions.SetTimer(handle, new UIntPtr(1), ModalLoopTimerPeriod, ModalLoopCallback);
if (timer_handle == UIntPtr.Zero) if (timer_handle == UIntPtr.Zero)
Debug.Print("[Warning] Failed to set modal loop timer callback ({0}:{1}->{2}).", Debug.Print("[Warning] Failed to set modal loop timer callback ({0}:{1}->{2}).",
GetType().Name, handle, Marshal.GetLastWin32Error()); GetType().Name, handle, Marshal.GetLastWin32Error());
@ -518,7 +509,7 @@ namespace OpenTK.Platform.Windows
#region IsIdle #region IsIdle
bool IsIdle bool IsIdle
{ {
get get
{ {
@ -609,6 +600,34 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
void HideBorder()
{
suppress_resize++;
WindowBorder = WindowBorder.Hidden;
ProcessEvents();
suppress_resize--;
}
void RestoreBorder()
{
suppress_resize++;
WindowBorder =
deferred_window_border.HasValue ? deferred_window_border.Value :
previous_window_border.HasValue ? previous_window_border.Value :
WindowBorder;
ProcessEvents();
suppress_resize--;
deferred_window_border = previous_window_border = null;
}
void ResetWindowState()
{
suppress_resize++;
WindowState = WindowState.Normal;
ProcessEvents();
suppress_resize--;
}
#endregion #endregion
#region INativeWindow Members #region INativeWindow Members
@ -699,7 +718,7 @@ namespace OpenTK.Platform.Windows
public int Width public int Width
{ {
get { return ClientRectangle.Width; } get { return ClientRectangle.Width; }
set { ClientRectangle = new Rectangle(Location, new Size(value, Height)); } set { ClientRectangle = new Rectangle(0, 0, value, Height); }
} }
#endregion #endregion
@ -709,7 +728,7 @@ namespace OpenTK.Platform.Windows
public int Height public int Height
{ {
get { return ClientRectangle.Height; } get { return ClientRectangle.Height; }
set { ClientRectangle = new Rectangle(Location, new Size(Width, value)); } set { ClientRectangle = new Rectangle(0, 0, Width, value); }
} }
#endregion #endregion
@ -718,8 +737,8 @@ namespace OpenTK.Platform.Windows
public int X public int X
{ {
get { return ClientRectangle.X; } get { return Location.X; }
set { ClientRectangle = new Rectangle(new Point(value, Y), Size); } set { Location = new Point(value, Y); }
} }
#endregion #endregion
@ -728,8 +747,8 @@ namespace OpenTK.Platform.Windows
public int Y public int Y
{ {
get { return ClientRectangle.Y; } get { return Location.Y; }
set { ClientRectangle = new Rectangle(new Point(X, value), Size); } set { Location = new Point(X, value); }
} }
#endregion #endregion
@ -798,6 +817,11 @@ namespace OpenTK.Platform.Windows
if (value) if (value)
{ {
Functions.ShowWindow(window.WindowHandle, ShowWindowCommand.SHOW); Functions.ShowWindow(window.WindowHandle, ShowWindowCommand.SHOW);
if (invisible_since_creation)
{
Functions.BringWindowToTop(window.WindowHandle);
Functions.SetForegroundWindow(window.WindowHandle);
}
} }
else if (!value) else if (!value)
{ {
@ -856,7 +880,7 @@ namespace OpenTK.Platform.Windows
// manually to cover the whole working area of the current monitor. // manually to cover the whole working area of the current monitor.
// Reset state to avoid strange interactions with fullscreen/minimized windows. // Reset state to avoid strange interactions with fullscreen/minimized windows.
WindowState = WindowState.Normal; ResetWindowState();
if (WindowBorder == WindowBorder.Hidden) if (WindowBorder == WindowBorder.Hidden)
{ {
@ -885,11 +909,11 @@ namespace OpenTK.Platform.Windows
// command for windows with hidden borders. // command for windows with hidden borders.
// Reset state to avoid strange side-effects from maximized/minimized windows. // Reset state to avoid strange side-effects from maximized/minimized windows.
WindowState = WindowState.Normal; ResetWindowState();
previous_bounds = Bounds; previous_bounds = Bounds;
previous_window_border = WindowBorder; previous_window_border = WindowBorder;
WindowBorder = WindowBorder.Hidden; HideBorder();
command = ShowWindowCommand.MAXIMIZE; command = ShowWindowCommand.MAXIMIZE;
Functions.SetForegroundWindow(window.WindowHandle); Functions.SetForegroundWindow(window.WindowHandle);
@ -900,22 +924,18 @@ namespace OpenTK.Platform.Windows
if (command != 0) if (command != 0)
Functions.ShowWindow(window.WindowHandle, command); Functions.ShowWindow(window.WindowHandle, command);
// Restore previous window border or apply pending border change when leaving fullscreen mode.
if (exiting_fullscreen)
{
RestoreBorder();
}
// Restore previous window size/location if necessary // Restore previous window size/location if necessary
if (command == ShowWindowCommand.RESTORE && previous_bounds != Rectangle.Empty) if (command == ShowWindowCommand.RESTORE && previous_bounds != Rectangle.Empty)
{ {
Bounds = previous_bounds; Bounds = previous_bounds;
previous_bounds = Rectangle.Empty; previous_bounds = Rectangle.Empty;
} }
// Restore previous window border or apply pending border change when leaving fullscreen mode.
if (exiting_fullscreen)
{
WindowBorder =
deferred_window_border.HasValue ? deferred_window_border.Value :
previous_window_border.HasValue ? previous_window_border.Value :
WindowBorder;
deferred_window_border = previous_window_border = null;
}
} }
} }
@ -950,7 +970,7 @@ namespace OpenTK.Platform.Windows
// To ensure maximized/minimized windows work correctly, reset state to normal, // To ensure maximized/minimized windows work correctly, reset state to normal,
// change the border, then go back to maximized/minimized. // change the border, then go back to maximized/minimized.
WindowState state = WindowState; WindowState state = WindowState;
WindowState = WindowState.Normal; ResetWindowState();
WindowStyle style = WindowStyle.ClipChildren | WindowStyle.ClipSiblings; WindowStyle style = WindowStyle.ClipChildren | WindowStyle.ClipSiblings;
@ -1061,7 +1081,7 @@ namespace OpenTK.Platform.Windows
public event EventHandler<EventArgs> MouseEnter; public event EventHandler<EventArgs> MouseEnter;
public event EventHandler<EventArgs> MouseLeave; public event EventHandler<EventArgs> MouseLeave;
#endregion #endregion
#endregion #endregion

View file

@ -15,6 +15,7 @@ using System.Drawing;
namespace OpenTK.Platform.Windows namespace OpenTK.Platform.Windows
{ {
/// \internal
/// <summary> /// <summary>
/// Contains methods to register for and process mouse WM_INPUT messages. /// Contains methods to register for and process mouse WM_INPUT messages.
/// </summary> /// </summary>

View file

@ -33,6 +33,7 @@ using System.Runtime.InteropServices;
namespace OpenTK.Platform.Windows namespace OpenTK.Platform.Windows
{ {
/// \internal
/// <summary>Describes a win32 window.</summary> /// <summary>Describes a win32 window.</summary>
sealed class WinWindowInfo : IWindowInfo sealed class WinWindowInfo : IWindowInfo
{ {

View file

@ -79,7 +79,10 @@ namespace OpenTK.Platform.X11
if (defaultDisplay == IntPtr.Zero) if (defaultDisplay == IntPtr.Zero)
throw new PlatformException("Could not establish connection to the X-Server."); throw new PlatformException("Could not establish connection to the X-Server.");
screenCount = Functions.XScreenCount(DefaultDisplay); using (new XLock(defaultDisplay))
{
screenCount = Functions.XScreenCount(DefaultDisplay);
}
Debug.Print("Display connection: {0}, Screen count: {1}", DefaultDisplay, ScreenCount); Debug.Print("Display connection: {0}, Screen count: {1}", DefaultDisplay, ScreenCount);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit); AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);

View file

@ -283,8 +283,10 @@ namespace OpenTK.Platform.X11
[DllImport(Library, EntryPoint = "glXDestroyContext")] [DllImport(Library, EntryPoint = "glXDestroyContext")]
public static extern void DestroyContext(IntPtr dpy, IntPtr context); public static extern void DestroyContext(IntPtr dpy, IntPtr context);
[DllImport(Library, EntryPoint = "glXDestroyContext")] public static void DestroyContext(IntPtr dpy, ContextHandle context)
public static extern void DestroyContext(IntPtr dpy, ContextHandle context); {
DestroyContext(dpy, context.Handle);
}
[DllImport(Library, EntryPoint = "glXGetCurrentContext")] [DllImport(Library, EntryPoint = "glXGetCurrentContext")]
public static extern IntPtr GetCurrentContext(); public static extern IntPtr GetCurrentContext();
@ -292,8 +294,10 @@ namespace OpenTK.Platform.X11
[DllImport(Library, EntryPoint = "glXMakeCurrent")] [DllImport(Library, EntryPoint = "glXMakeCurrent")]
public static extern bool MakeCurrent(IntPtr display, IntPtr drawable, IntPtr context); public static extern bool MakeCurrent(IntPtr display, IntPtr drawable, IntPtr context);
[DllImport(Library, EntryPoint = "glXMakeCurrent")] public static bool MakeCurrent(IntPtr display, IntPtr drawable, ContextHandle context)
public static extern bool MakeCurrent(IntPtr display, IntPtr drawable, ContextHandle context); {
return MakeCurrent(display, drawable, context.Handle);
}
[DllImport(Library, EntryPoint = "glXSwapBuffers")] [DllImport(Library, EntryPoint = "glXSwapBuffers")]
public static extern void SwapBuffers(IntPtr display, IntPtr drawable); public static extern void SwapBuffers(IntPtr display, IntPtr drawable);

View file

@ -42,35 +42,6 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region DisplayLock
/*
internal class DisplayLock : IDisposable
{
IntPtr display;
public DisplayLock(IntPtr display)
{
if (display == IntPtr.Zero) throw new ArgumentException("display", "Must be a valid X11 display connection.");
this.display = display;
Functions.XLockDisplay(display);
}
publc void Dispose()
{
Functions.XUnlockDisplay(display);
GC.SuppressFinalize(this);
}
~DisplayLock()
{
Functions.XUnlockDisplay(display);
}
}
*/
#endregion
#region Structs #region Structs
#endregion #endregion
@ -140,8 +111,7 @@ namespace OpenTK.Platform.X11
[DllImport("libX11", EntryPoint = "XMoveResizeWindow")] [DllImport("libX11", EntryPoint = "XMoveResizeWindow")]
public extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height); public extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
[DllImport("libX11", EntryPoint = "XMoveWindow")]
[DllImport("libX11", EntryPoint = "XResizeWindow")]
public extern static int XMoveWindow(IntPtr display, IntPtr w, int x, int y); public extern static int XMoveWindow(IntPtr display, IntPtr w, int x, int y);
[DllImport("libX11", EntryPoint = "XResizeWindow")] [DllImport("libX11", EntryPoint = "XResizeWindow")]

View file

@ -68,15 +68,23 @@ namespace OpenTK.Platform.X11
// Create a temporary context to obtain the necessary function pointers. // Create a temporary context to obtain the necessary function pointers.
XVisualInfo visual = currentWindow.VisualInfo; XVisualInfo visual = currentWindow.VisualInfo;
IntPtr ctx = Glx.CreateContext(Display, ref visual, IntPtr.Zero, true); IntPtr ctx = IntPtr.Zero;
if (ctx == IntPtr.Zero)
ctx = Glx.CreateContext(Display, ref visual, IntPtr.Zero, false); using (new XLock(Display))
{
ctx = Glx.CreateContext(Display, ref visual, IntPtr.Zero, true);
if (ctx == IntPtr.Zero)
ctx = Glx.CreateContext(Display, ref visual, IntPtr.Zero, false);
}
if (ctx != IntPtr.Zero) if (ctx != IntPtr.Zero)
{ {
new Glx().LoadEntryPoints(); new Glx().LoadEntryPoints();
Glx.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero); using (new XLock(Display))
//Glx.DestroyContext(Display, ctx); {
Glx.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero);
//Glx.DestroyContext(Display, ctx);
}
glx_loaded = true; glx_loaded = true;
} }
} }
@ -121,15 +129,18 @@ namespace OpenTK.Platform.X11
// Is this a single 0, or a <0, 0> pair? (Defensive coding: add two zeroes just in case). // Is this a single 0, or a <0, 0> pair? (Defensive coding: add two zeroes just in case).
attributes.Add(0); attributes.Add(0);
attributes.Add(0); attributes.Add(0);
Handle = new ContextHandle(Glx.Arb.CreateContextAttribs(Display, *fbconfigs, using (new XLock(Display))
shareHandle.Handle, direct, attributes.ToArray()));
if (Handle == ContextHandle.Zero)
{ {
Debug.Write(String.Format("failed. Trying direct: {0}... ", !direct));
Handle = new ContextHandle(Glx.Arb.CreateContextAttribs(Display, *fbconfigs, Handle = new ContextHandle(Glx.Arb.CreateContextAttribs(Display, *fbconfigs,
shareHandle.Handle, !direct, attributes.ToArray())); shareHandle.Handle, direct, attributes.ToArray()));
if (Handle == ContextHandle.Zero)
{
Debug.Write(String.Format("failed. Trying direct: {0}... ", !direct));
Handle = new ContextHandle(Glx.Arb.CreateContextAttribs(Display, *fbconfigs,
shareHandle.Handle, !direct, attributes.ToArray()));
}
} }
if (Handle == ContextHandle.Zero) if (Handle == ContextHandle.Zero)
@ -150,13 +161,16 @@ namespace OpenTK.Platform.X11
Debug.Write("Using legacy context creation... "); Debug.Write("Using legacy context creation... ");
XVisualInfo info = currentWindow.VisualInfo; XVisualInfo info = currentWindow.VisualInfo;
// Cannot pass a Property by reference. using (new XLock(Display))
Handle = new ContextHandle(Glx.CreateContext(Display, ref info, shareHandle.Handle, direct));
if (Handle == ContextHandle.Zero)
{ {
Debug.WriteLine(String.Format("failed. Trying direct: {0}... ", !direct)); // Cannot pass a Property by reference.
Handle = new ContextHandle(Glx.CreateContext(Display, ref info, IntPtr.Zero, !direct)); Handle = new ContextHandle(Glx.CreateContext(Display, ref info, shareHandle.Handle, direct));
if (Handle == ContextHandle.Zero)
{
Debug.WriteLine(String.Format("failed. Trying direct: {0}... ", !direct));
Handle = new ContextHandle(Glx.CreateContext(Display, ref info, IntPtr.Zero, !direct));
}
} }
} }
@ -164,9 +178,12 @@ namespace OpenTK.Platform.X11
Debug.Print("Context created (id: {0}).", Handle); Debug.Print("Context created (id: {0}).", Handle);
else else
throw new GraphicsContextException("Failed to create OpenGL context. Glx.CreateContext call returned 0."); throw new GraphicsContextException("Failed to create OpenGL context. Glx.CreateContext call returned 0.");
if (!Glx.IsDirect(Display, Handle.Handle)) using (new XLock(Display))
Debug.Print("Warning: Context is not direct."); {
if (!Glx.IsDirect(Display, Handle.Handle))
Debug.Print("Warning: Context is not direct.");
}
} }
public X11GLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shared, bool direct, public X11GLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shared, bool direct,
@ -232,7 +249,11 @@ namespace OpenTK.Platform.X11
if (window.Display != Display) if (window.Display != Display)
throw new InvalidOperationException(); throw new InvalidOperationException();
string extensions = Glx.QueryExtensionsString(Display, window.Screen); string extensions = null;
using (new XLock(Display))
{
extensions = Glx.QueryExtensionsString(Display, window.Screen);
}
return !String.IsNullOrEmpty(extensions) && extensions.Contains(e); return !String.IsNullOrEmpty(extensions) && extensions.Contains(e);
} }
@ -247,7 +268,10 @@ namespace OpenTK.Platform.X11
if (Display == IntPtr.Zero || currentWindow.WindowHandle == IntPtr.Zero) if (Display == IntPtr.Zero || currentWindow.WindowHandle == IntPtr.Zero)
throw new InvalidOperationException( throw new InvalidOperationException(
String.Format("Window is invalid. Display ({0}), Handle ({1}).", Display, currentWindow.WindowHandle)); String.Format("Window is invalid. Display ({0}), Handle ({1}).", Display, currentWindow.WindowHandle));
Glx.SwapBuffers(Display, currentWindow.WindowHandle); using (new XLock(Display))
{
Glx.SwapBuffers(Display, currentWindow.WindowHandle);
}
} }
#endregion #endregion
@ -264,7 +288,19 @@ namespace OpenTK.Platform.X11
if (window == null) if (window == null)
{ {
Glx.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero); Debug.Write(String.Format("Releasing context {0} from thread {1} (Display: {2})... ",
Handle, System.Threading.Thread.CurrentThread.ManagedThreadId, Display));
bool result;
using (new XLock(Display))
{
result = Glx.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero);
if (result)
{
currentWindow = null;
}
}
Debug.Print("{0}", result ? "done!" : "failed.");
} }
else else
{ {
@ -277,7 +313,14 @@ namespace OpenTK.Platform.X11
if (Display == IntPtr.Zero || w.WindowHandle == IntPtr.Zero || Handle == ContextHandle.Zero) if (Display == IntPtr.Zero || w.WindowHandle == IntPtr.Zero || Handle == ContextHandle.Zero)
throw new InvalidOperationException("Invalid display, window or context."); throw new InvalidOperationException("Invalid display, window or context.");
result = Glx.MakeCurrent(Display, w.WindowHandle, Handle); using (new XLock(Display))
{
result = Glx.MakeCurrent(Display, w.WindowHandle, Handle);
if (result)
{
currentWindow = w;
}
}
if (!result) if (!result)
throw new GraphicsContextException("Failed to make context current."); throw new GraphicsContextException("Failed to make context current.");
@ -294,7 +337,13 @@ namespace OpenTK.Platform.X11
public override bool IsCurrent public override bool IsCurrent
{ {
get { return Glx.GetCurrentContext() == Handle.Handle; } get
{
using (new XLock(Display))
{
return Glx.GetCurrentContext() == Handle.Handle;
}
}
} }
#endregion #endregion
@ -311,7 +360,11 @@ namespace OpenTK.Platform.X11
{ {
if (vsync_supported) if (vsync_supported)
{ {
ErrorCode error_code = Glx.Sgi.SwapInterval(value ? 1 : 0); ErrorCode error_code = 0;
using (new XLock(Display))
{
error_code = Glx.Sgi.SwapInterval(value ? 1 : 0);
}
if (error_code != X11.ErrorCode.NO_ERROR) if (error_code != X11.ErrorCode.NO_ERROR)
Debug.Print("VSync = {0} failed, error code: {1}.", value, error_code); Debug.Print("VSync = {0} failed, error code: {1}.", value, error_code);
vsync_interval = value ? 1 : 0; vsync_interval = value ? 1 : 0;
@ -325,7 +378,10 @@ namespace OpenTK.Platform.X11
public override IntPtr GetAddress(string function) public override IntPtr GetAddress(string function)
{ {
return Glx.GetProcAddress(function); using (new XLock(Display))
{
return Glx.GetProcAddress(function);
}
} }
#endregion #endregion
@ -370,18 +426,27 @@ namespace OpenTK.Platform.X11
if (manuallyCalled) if (manuallyCalled)
{ {
IntPtr display = Display; IntPtr display = Display;
if (IsCurrent)
Glx.MakeCurrent(display, IntPtr.Zero, IntPtr.Zero);
Glx.DestroyContext(display, Handle); if (IsCurrent)
{
using (new XLock(display))
{
Glx.MakeCurrent(display, IntPtr.Zero, IntPtr.Zero);
}
}
using (new XLock(display))
{
Glx.DestroyContext(display, Handle);
}
} }
else
{
Debug.Print("[Warning] {0} leaked.", this.GetType().Name);
}
IsDisposed = true;
} }
else
{
Debug.Print("[Warning] {0} leaked.", this.GetType().Name);
}
IsDisposed = true;
} }
~X11GLContext() ~X11GLContext()
{ {

View file

@ -81,6 +81,8 @@ namespace OpenTK.Platform.X11
IntPtr _atom_net_wm_icon; IntPtr _atom_net_wm_icon;
IntPtr _atom_net_frame_extents;
readonly IntPtr _atom_xa_cardinal = new IntPtr(6); readonly IntPtr _atom_xa_cardinal = new IntPtr(6);
//IntPtr _atom_motif_wm_hints; //IntPtr _atom_motif_wm_hints;
@ -92,7 +94,7 @@ namespace OpenTK.Platform.X11
static readonly IntPtr _atom_toggle = (IntPtr)2; static readonly IntPtr _atom_toggle = (IntPtr)2;
Rectangle bounds, client_rectangle; Rectangle bounds, client_rectangle;
int border_width; int border_left, border_right, border_top, border_bottom;
Icon icon; Icon icon;
bool has_focus; bool has_focus;
bool visible; bool visible;
@ -145,7 +147,7 @@ namespace OpenTK.Platform.X11
attributes.background_pixel = IntPtr.Zero; attributes.background_pixel = IntPtr.Zero;
attributes.border_pixel = IntPtr.Zero; attributes.border_pixel = IntPtr.Zero;
attributes.colormap = Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.Visual, 0/*AllocNone*/); attributes.colormap = Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.Visual, 0/*AllocNone*/);
window.EventMask = EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask | window.EventMask = EventMask.StructureNotifyMask /*| EventMask.SubstructureNotifyMask*/ | EventMask.ExposureMask |
EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeymapStateMask | EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeymapStateMask |
EventMask.PointerMotionMask | EventMask.FocusChangeMask | EventMask.PointerMotionMask | EventMask.FocusChangeMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.ButtonPressMask | EventMask.ButtonReleaseMask |
@ -206,7 +208,6 @@ namespace OpenTK.Platform.X11
using (new XLock(window.Display)) using (new XLock(window.Display))
{ {
Functions.XLockDisplay(window.Display);
window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen; window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
window.RootWindow = Functions.XRootWindow(window.Display, window.Screen); // API.RootWindow; window.RootWindow = Functions.XRootWindow(window.Display, window.Screen); // API.RootWindow;
} }
@ -258,6 +259,9 @@ namespace OpenTK.Platform.X11
_atom_net_wm_icon = _atom_net_wm_icon =
Functions.XInternAtom(window.Display, "_NEW_WM_ICON", false); Functions.XInternAtom(window.Display, "_NEW_WM_ICON", false);
_atom_net_frame_extents =
Functions.XInternAtom(window.Display, "_NET_FRAME_EXTENTS", false);
// string[] atom_names = new string[] // string[] atom_names = new string[]
// { // {
@ -407,14 +411,14 @@ namespace OpenTK.Platform.X11
Debug.Print("Removed decorations through motif."); Debug.Print("Removed decorations through motif.");
_decorations_hidden = true; _decorations_hidden = true;
} }
using (new XLock(window.Display)) using (new XLock(window.Display))
{ {
// Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow); // Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow);
// Some WMs remove decorations when this hint is set. Doesn't hurt to try. // Some WMs remove decorations when this hint is set. Doesn't hurt to try.
Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow); Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow);
if (_decorations_hidden) if (_decorations_hidden)
{ {
Functions.XUnmapWindow(this.window.Display, this.Handle); Functions.XUnmapWindow(this.window.Display, this.Handle);
@ -422,23 +426,27 @@ namespace OpenTK.Platform.X11
} }
} }
} }
#region bool DisableMotifDecorations() #region bool DisableMotifDecorations()
bool DisableMotifDecorations() bool DisableMotifDecorations()
{ {
IntPtr atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true); using (new XLock(window.Display))
if (atom != IntPtr.Zero)
{ {
//Functions.XGetWindowProperty(window.Display, window.WindowHandle, atom, IntPtr.Zero, IntPtr.Zero, false, IntPtr atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true);
if (atom != IntPtr.Zero)
MotifWmHints hints = new MotifWmHints(); {
hints.flags = (IntPtr)MotifFlags.Decorations; //Functions.XGetWindowProperty(window.Display, window.WindowHandle, atom, IntPtr.Zero, IntPtr.Zero, false,
Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace,
ref hints, Marshal.SizeOf(hints) / IntPtr.Size); MotifWmHints hints = new MotifWmHints();
return true; hints.flags = (IntPtr)MotifFlags.Decorations;
Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace,
ref hints, Marshal.SizeOf(hints) / IntPtr.Size);
return true;
}
return false;
} }
return false;
} }
#endregion #endregion
@ -447,16 +455,19 @@ namespace OpenTK.Platform.X11
bool DisableGnomeDecorations() bool DisableGnomeDecorations()
{ {
IntPtr atom = Functions.XInternAtom(this.window.Display, Constants.XA_WIN_HINTS, true); using (new XLock(window.Display))
if (atom != IntPtr.Zero)
{ {
IntPtr hints = IntPtr.Zero; IntPtr atom = Functions.XInternAtom(this.window.Display, Constants.XA_WIN_HINTS, true);
Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace, if (atom != IntPtr.Zero)
ref hints, Marshal.SizeOf(hints) / IntPtr.Size); {
return true; IntPtr hints = IntPtr.Zero;
Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace,
ref hints, Marshal.SizeOf(hints) / IntPtr.Size);
return true;
}
return false;
} }
return false;
} }
#endregion #endregion
@ -478,7 +489,7 @@ namespace OpenTK.Platform.X11
using (new XLock(window.Display)) using (new XLock(window.Display))
{ {
Functions.XSetTransientForHint(this.window.Display, this.Handle, IntPtr.Zero); Functions.XSetTransientForHint(this.window.Display, this.Handle, IntPtr.Zero);
if (!_decorations_hidden) if (!_decorations_hidden)
{ {
Functions.XUnmapWindow(this.window.Display, this.Handle); Functions.XUnmapWindow(this.window.Display, this.Handle);
@ -574,6 +585,86 @@ namespace OpenTK.Platform.X11
#endregion #endregion
bool RefreshWindowBorders()
{
IntPtr atom, nitems, bytes_after, prop = IntPtr.Zero;
int format;
bool borders_changed = false;
using (new XLock(window.Display))
{
Functions.XGetWindowProperty(window.Display, window.WindowHandle,
_atom_net_frame_extents, IntPtr.Zero, new IntPtr(16), false,
(IntPtr)Atom.XA_CARDINAL, out atom, out format, out nitems, out bytes_after, ref prop);
}
if ((prop != IntPtr.Zero))
{
if ((long)nitems == 4)
{
int new_border_left = Marshal.ReadIntPtr(prop, 0).ToInt32();
int new_border_right = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
int new_border_top = Marshal.ReadIntPtr(prop, IntPtr.Size * 2).ToInt32();
int new_border_bottom = Marshal.ReadIntPtr(prop, IntPtr.Size * 3).ToInt32();
borders_changed =
new_border_left != border_left ||
new_border_right != border_right ||
new_border_top != border_top ||
new_border_bottom != border_bottom;
border_left = new_border_left;
border_right = new_border_right;
border_top = new_border_top;
border_bottom = new_border_bottom;
//Debug.WriteLine(border_left);
//Debug.WriteLine(border_right);
//Debug.WriteLine(border_top);
//Debug.WriteLine(border_bottom);
}
using (new XLock(window.Display))
{
Functions.XFree(prop);
}
}
return borders_changed;
}
void RefreshWindowBounds(ref XEvent e)
{
RefreshWindowBorders();
Point new_location = new Point(
e.ConfigureEvent.x - border_left,
e.ConfigureEvent.y - border_top);
if (Location != new_location)
{
bounds.Location = new_location;
if (Move != null)
Move(this, EventArgs.Empty);
}
// Note: width and height denote the internal (client) size.
// To get the external (window) size, we need to add the border size.
Size new_size = new Size(
e.ConfigureEvent.width + border_left + border_right,
e.ConfigureEvent.height + border_top + border_bottom);
if (Bounds.Size != new_size)
{
bounds.Size = new_size;
client_rectangle.Size = new Size(e.ConfigureEvent.width, e.ConfigureEvent.height);
if (this.Resize != null)
{
//Debug.WriteLine(new System.Diagnostics.StackTrace());
Resize(this, EventArgs.Empty);
}
}
}
#endregion #endregion
#region INativeWindow Members #region INativeWindow Members
@ -583,10 +674,15 @@ namespace OpenTK.Platform.X11
public void ProcessEvents() public void ProcessEvents()
{ {
// Process all pending events // Process all pending events
while (Exists && window != null && while (Exists && window != null)
Functions.XCheckWindowEvent(window.Display, window.WindowHandle, window.EventMask, ref e) ||
Functions.XCheckTypedWindowEvent(window.Display, window.WindowHandle, XEventName.ClientMessage, ref e))
{ {
using (new XLock(window.Display))
{
if (!Functions.XCheckWindowEvent(window.Display, window.WindowHandle, window.EventMask, ref e) &&
!Functions.XCheckTypedWindowEvent(window.Display, window.WindowHandle, XEventName.ClientMessage, ref e))
break;
}
// Respond to the event e // Respond to the event e
switch (e.type) switch (e.type)
{ {
@ -627,7 +723,10 @@ namespace OpenTK.Platform.X11
isExiting = true; isExiting = true;
Debug.WriteLine("Destroying window."); Debug.WriteLine("Destroying window.");
Functions.XDestroyWindow(window.Display, window.WindowHandle); using (new XLock(window.Display))
{
Functions.XDestroyWindow(window.Display, window.WindowHandle);
}
break; break;
} }
} }
@ -644,37 +743,13 @@ namespace OpenTK.Platform.X11
return; return;
case XEventName.ConfigureNotify: case XEventName.ConfigureNotify:
border_width = e.ConfigureEvent.border_width; RefreshWindowBounds(ref e);
Point new_location = new Point(e.ConfigureEvent.x, e.ConfigureEvent.y);
if (Location != new_location)
{
bounds.Location = new_location;
if (Move != null)
Move(this, EventArgs.Empty);
}
// Note: width and height denote the internal (client) size.
// To get the external (window) size, we need to add the border size.
Size new_size = new Size(e.ConfigureEvent.width, e.ConfigureEvent.height);
if (ClientSize != new_size)
{
bounds.Size = new_size;
bounds.Width += e.ConfigureEvent.border_width;
bounds.Height += e.ConfigureEvent.border_width;
// Todo: Get the real client rectangle.
client_rectangle.Size = new_size;
if (this.Resize != null)
Resize(this, EventArgs.Empty);
}
break; break;
case XEventName.KeyPress: case XEventName.KeyPress:
driver.ProcessEvent(ref e); driver.ProcessEvent(ref e);
int status = 0;
int status = Functions.XLookupString(ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero); status = Functions.XLookupString(ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero);
Encoding.Default.GetChars(ascii, 0, status, chars, 0); Encoding.Default.GetChars(ascii, 0, status, chars, 0);
EventHandler<KeyPressEventArgs> key_press = KeyPress; EventHandler<KeyPressEventArgs> key_press = KeyPress;
@ -741,9 +816,16 @@ namespace OpenTK.Platform.X11
break; break;
case XEventName.PropertyNotify: case XEventName.PropertyNotify:
if (e.PropertyEvent.atom == _atom_net_wm_state) if (e.PropertyEvent.atom == _atom_net_wm_state)
{
if (WindowStateChanged != null) if (WindowStateChanged != null)
WindowStateChanged(this, EventArgs.Empty); WindowStateChanged(this, EventArgs.Empty);
}
//if (e.PropertyEvent.atom == _atom_net_frame_extents)
//{
// RefreshWindowBorders();
//}
break; break;
default: default:
@ -762,8 +844,15 @@ namespace OpenTK.Platform.X11
get { return bounds; } get { return bounds; }
set set
{ {
Functions.XMoveResizeWindow(window.Display, window.WindowHandle, using (new XLock(window.Display))
value.X, value.Y, value.Width - border_width, value.Height - border_width); {
Functions.XMoveResizeWindow(window.Display, window.WindowHandle,
value.X,
value.Y,
value.Width - border_left - border_right,
value.Height - border_top - border_bottom);
}
ProcessEvents();
} }
} }
@ -776,7 +865,11 @@ namespace OpenTK.Platform.X11
get { return Bounds.Location; } get { return Bounds.Location; }
set set
{ {
Functions.XMoveWindow(window.Display, window.WindowHandle, value.X, value.Y); using (new XLock(window.Display))
{
Functions.XMoveWindow(window.Display, window.WindowHandle, value.X, value.Y);
}
ProcessEvents();
} }
} }
@ -789,12 +882,16 @@ namespace OpenTK.Platform.X11
get { return Bounds.Size; } get { return Bounds.Size; }
set set
{ {
int width = value.Width - border_width; int width = value.Width - border_left - border_right;
int height = value.Height - border_width; int height = value.Height - border_top - border_bottom;
width = width < 0 ? 1 : width; width = width <= 0 ? 1 : width;
height = height < 0 ? 1 : height; height = height <= 0 ? 1 : height;
Functions.XResizeWindow(window.Display, window.WindowHandle, width, height); using (new XLock(window.Display))
{
Functions.XResizeWindow(window.Display, window.WindowHandle, width, height);
}
ProcessEvents();
} }
} }
@ -814,8 +911,12 @@ namespace OpenTK.Platform.X11
} }
set set
{ {
Functions.XResizeWindow(window.Display, window.WindowHandle, using (new XLock(window.Display))
value.Width, value.Height); {
Functions.XResizeWindow(window.Display, window.WindowHandle,
value.Width, value.Height);
}
ProcessEvents();
} }
} }
@ -841,8 +942,8 @@ namespace OpenTK.Platform.X11
public int Width public int Width
{ {
get { return Bounds.Width; } get { return ClientSize.Width; }
set { Size = new Size(value, Height); } set { ClientSize = new Size(value, Height); }
} }
#endregion #endregion
@ -851,8 +952,8 @@ namespace OpenTK.Platform.X11
public int Height public int Height
{ {
get { return Bounds.Height; } get { return ClientSize.Height; }
set { Size = new Size(Width, value); } set { ClientSize = new Size(Width, value); }
} }
#endregion #endregion
@ -861,7 +962,7 @@ namespace OpenTK.Platform.X11
public int X public int X
{ {
get { return Bounds.X; } get { return Location.X; }
set { Location = new Point(value, Y); } set { Location = new Point(value, Y); }
} }
@ -871,7 +972,7 @@ namespace OpenTK.Platform.X11
public int Y public int Y
{ {
get { return Bounds.Y; } get { return Location.Y; }
set { Location = new Point(X, value); } set { Location = new Point(X, value); }
} }
@ -1094,6 +1195,8 @@ namespace OpenTK.Platform.X11
if (temporary_resizable) if (temporary_resizable)
WindowBorder = previous_state; WindowBorder = previous_state;
ProcessEvents();
} }
} }
@ -1245,7 +1348,10 @@ namespace OpenTK.Platform.X11
get get
{ {
IntPtr name = IntPtr.Zero; IntPtr name = IntPtr.Zero;
Functions.XFetchName(window.Display, window.WindowHandle, ref name); using (new XLock(window.Display))
{
Functions.XFetchName(window.Display, window.WindowHandle, ref name);
}
if (name != IntPtr.Zero) if (name != IntPtr.Zero)
return Marshal.PtrToStringAnsi(name); return Marshal.PtrToStringAnsi(name);
@ -1254,7 +1360,12 @@ namespace OpenTK.Platform.X11
set set
{ {
if (value != null && value != Title) if (value != null && value != Title)
Functions.XStoreName(window.Display, window.WindowHandle, value); {
using (new XLock(window.Display))
{
Functions.XStoreName(window.Display, window.WindowHandle, value);
}
}
if (TitleChanged != null) if (TitleChanged != null)
TitleChanged(this, EventArgs.Empty); TitleChanged(this, EventArgs.Empty);
@ -1275,11 +1386,17 @@ namespace OpenTK.Platform.X11
{ {
if (value && !visible) if (value && !visible)
{ {
Functions.XMapWindow(window.Display, window.WindowHandle); using (new XLock(window.Display))
{
Functions.XMapWindow(window.Display, window.WindowHandle);
}
} }
else if (!value && visible) else if (!value && visible)
{ {
Functions.XUnmapWindow(window.Display, window.WindowHandle); using (new XLock(window.Display))
{
Functions.XUnmapWindow(window.Display, window.WindowHandle);
}
} }
} }
} }
@ -1307,9 +1424,12 @@ namespace OpenTK.Platform.X11
ev.ClientMessageEvent.display = window.Display; ev.ClientMessageEvent.display = window.Display;
ev.ClientMessageEvent.window = window.WindowHandle; ev.ClientMessageEvent.window = window.WindowHandle;
ev.ClientMessageEvent.ptr1 = _atom_wm_destroy; ev.ClientMessageEvent.ptr1 = _atom_wm_destroy;
Functions.XSendEvent(window.Display, window.WindowHandle, false, using (new XLock(window.Display))
EventMask.NoEventMask, ref ev); {
Functions.XFlush(window.Display); Functions.XSendEvent(window.Display, window.WindowHandle, false,
EventMask.NoEventMask, ref ev);
Functions.XFlush(window.Display);
}
} }
#endregion #endregion
@ -1319,7 +1439,10 @@ namespace OpenTK.Platform.X11
public void DestroyWindow() public void DestroyWindow()
{ {
Debug.WriteLine("X11GLNative shutdown sequence initiated."); Debug.WriteLine("X11GLNative shutdown sequence initiated.");
Functions.XDestroyWindow(window.Display, window.WindowHandle); using (new XLock(window.Display))
{
Functions.XDestroyWindow(window.Display, window.WindowHandle);
}
} }
#endregion #endregion
@ -1331,7 +1454,10 @@ namespace OpenTK.Platform.X11
int ox, oy; int ox, oy;
IntPtr child; IntPtr child;
Functions.XTranslateCoordinates(window.Display, window.RootWindow, window.WindowHandle, point.X, point.Y, out ox, out oy, out child); using (new XLock(window.Display))
{
Functions.XTranslateCoordinates(window.Display, window.RootWindow, window.WindowHandle, point.X, point.Y, out ox, out oy, out child);
}
point.X = ox; point.X = ox;
point.Y = oy; point.Y = oy;
@ -1348,7 +1474,10 @@ namespace OpenTK.Platform.X11
int ox, oy; int ox, oy;
IntPtr child; IntPtr child;
Functions.XTranslateCoordinates(window.Display, window.WindowHandle, window.RootWindow, point.X, point.Y, out ox, out oy, out child); using (new XLock(window.Display))
{
Functions.XTranslateCoordinates(window.Display, window.WindowHandle, window.RootWindow, point.X, point.Y, out ox, out oy, out child);
}
point.X = ox; point.X = ox;
point.Y = oy; point.Y = oy;
@ -1378,15 +1507,10 @@ namespace OpenTK.Platform.X11
{ {
if (Exists) if (Exists)
{ {
try using (new XLock(window.Display))
{ {
Functions.XLockDisplay(window.Display);
Functions.XDestroyWindow(window.Display, window.WindowHandle); Functions.XDestroyWindow(window.Display, window.WindowHandle);
} }
finally
{
Functions.XUnlockDisplay(window.Display);
}
while (Exists) while (Exists)
ProcessEvents(); ProcessEvents();

View file

@ -165,36 +165,33 @@ namespace OpenTK.Platform.X11
// Select a visual that matches the parameters set by the user. // Select a visual that matches the parameters set by the user.
IntPtr display = API.DefaultDisplay; IntPtr display = API.DefaultDisplay;
try using (new XLock(display))
{ {
Functions.XLockDisplay(display); try
int screen = Functions.XDefaultScreen(display);
IntPtr root = Functions.XRootWindow(display, screen);
Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
unsafe
{ {
Debug.Print("Getting FB config."); int screen = Functions.XDefaultScreen(display);
int fbcount; IntPtr root = Functions.XRootWindow(display, screen);
// Note that ChooseFBConfig returns an array of GLXFBConfig opaque structures (i.e. mapped to IntPtrs). Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
IntPtr* fbconfigs = Glx.ChooseFBConfig(display, screen, visualAttributes.ToArray(), out fbcount);
if (fbcount > 0 && fbconfigs != null) unsafe
{ {
// We want to use the first GLXFBConfig from the fbconfigs array (the first one is the best match). Debug.Print("Getting FB config.");
visual = Glx.GetVisualFromFBConfig(display, *fbconfigs); int fbcount;
Functions.XFree((IntPtr)fbconfigs); // Note that ChooseFBConfig returns an array of GLXFBConfig opaque structures (i.e. mapped to IntPtrs).
IntPtr* fbconfigs = Glx.ChooseFBConfig(display, screen, visualAttributes.ToArray(), out fbcount);
if (fbcount > 0 && fbconfigs != null)
{
// We want to use the first GLXFBConfig from the fbconfigs array (the first one is the best match).
visual = Glx.GetVisualFromFBConfig(display, *fbconfigs);
Functions.XFree((IntPtr)fbconfigs);
}
} }
} }
} catch (EntryPointNotFoundException)
catch (EntryPointNotFoundException) {
{ Debug.Print("Function glXChooseFBConfig not supported.");
Debug.Print("Function glXChooseFBConfig not supported."); return IntPtr.Zero;
return IntPtr.Zero; }
}
finally
{
Functions.XUnlockDisplay(display);
} }
return visual; return visual;
@ -266,15 +263,10 @@ namespace OpenTK.Platform.X11
Debug.Print("Falling back to glXChooseVisual."); Debug.Print("Falling back to glXChooseVisual.");
IntPtr display = API.DefaultDisplay; IntPtr display = API.DefaultDisplay;
try using (new XLock(display))
{ {
Functions.XLockDisplay(display);
return Glx.ChooseVisual(display, Functions.XDefaultScreen(display), visualAttributes.ToArray()); return Glx.ChooseVisual(display, Functions.XDefaultScreen(display), visualAttributes.ToArray());
} }
finally
{
Functions.XUnlockDisplay(display);
}
} }
#endregion #endregion

View file

@ -11,7 +11,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("The Open Toolkit Library")] [assembly: AssemblyCompany("The Open Toolkit Library")]
[assembly: AssemblyProduct("The Open Toolkit Library")] [assembly: AssemblyProduct("The Open Toolkit Library")]
[assembly: AssemblyCopyright("Copyright © 2006-2009 the Open Toolkit Library")] [assembly: AssemblyCopyright("Copyright © 2006-2010 the Open Toolkit Library")]
[assembly: AssemblyTrademark("OpenTK")] [assembly: AssemblyTrademark("OpenTK")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
@ -40,4 +40,4 @@ using System.Runtime.InteropServices;
#if SIGN_ASSEMBLY #if SIGN_ASSEMBLY
[assembly: AssemblyKeyFile(@"../../../OpenTK.snk")] [assembly: AssemblyKeyFile(@"../../../OpenTK.snk")]
#endif #endif