joyGetDevCaps() is an extremely slow call that allocates memory.
WinMMJoystick is now caching its results for a significant speedup in
Joystick.GetCapabilities() and GetState().
The cache is updated whenever a joystick device is removed. WIP to
handle device added notifications.
This protects against a potential denial-of-service issue during mode
selection, where the platform backend will try to reduce AA level until
a supported mode is found.
When refreshing the AvailableDevices list, it is important to set the
original resolution on any DisplayDevices that were previously available
to allow the RestoreResolution() method to work correctly.
Creating a GraphicsContext with null parameters is not a guarantee that
we will get a dummy context that does not call any OpenGL functions. We
need to explicitly define and construct a dummy context that is safe to
use inside the designer.
Affects issue #49
Most OpenGL versions work with single-byte ASCII strings exclusively.
OpenGL 4.2 adds UTF8 encoded comments to GLSL shaders. Unfortunately,
UTF16 (.Net) to UTF8 conversions will usually modify the length of the
resulting byte array.
This is not currently possible to implement inside OpenTK, since the
binding generator does not know which length parameter corresponds to a
string parameter.
For this reason, and to maintain compatibility with older OpenGL
versions, we perform a destructive UTF16-to-ASCII encoding, which
replaces unsupported characters by '?'. This allows multi-byte post-4.2.
GLSL shaders to work as expected.
If non-destructive round-tripping of strings is required, the user will
have to use the IntPtr overload for string parameters and perform the
UTF16-to-UTF8 encoding/decoding manually. This need is very unlikely to
arise in practice.
OpenTK will now detect when an UpdateFrame handler is consistently
taking too long to finish, and stop raising UpdateFrame events. This
gives ProcessEvents() a chance to execute and will protect the
application from hanging up.
GameWindowStates will now display the average fps and draw three moving
boxes based on different timing methods.
If the timing implementation in OpenTK is working correctly, all three
boxes should be moving at the same speed.
The UpdateFrame event rate will now match TargetUpdatePeriod even if
vsync is enabled. Previously, it would be quantized to a multiple or
integer fraction of of the vsync rate.
Alc.GetString() could crash if the unmanaged code returned null due to
any kind of failure. This is now fixed and better documented.
Additionally, the array overload for Alc.GetString() will now correctly
forward the ‘device’ parameter to unmanaged code.
Multiple UpdateFrame events should be raised to match the desired
TargetUpdateFrequency, when TargetUpdateFrequency > 0. The loop would
incorrectly check for TargetRenderFrequency instead.
Affects issue #43
This patch adds more robust checks for WGL_ARB_pixel_format and
WGL_ARB_multisample before using the relevant extensions, and adds
checks whether Wgl.Arb.ChoosePixelFormat() returns a valid pixel format
before trying to use it (thanks to Repetier for catching this edge
case.)
Additionally, the ChoosePixelFormatPFD code-path now heavily penalizes
single-buffered modes when the user requests a double-buffered mode.
Affects issues #42 and #45
SDL will fail to construct an OpenGL 3.x/4.x context on Mac OS X,
unless ContextProfileFlags.CORE is specified.
Fixes issue #44
Upstream enhancement request at
https://bugzilla.libsdl.org/show_bug.cgi?id=2342
When running over remote desktop without hardware acceleration, there
are no GraphicsModes that support desktop composition. This patch adds
logic to avoid requesting composition-capable modes when running over
RDP.
Additionally, it changes the mode selection logic to consider modes that
support features partially (e.g. 16bpp color instead of 32bpp), albeit
with a heavy penalty over fully supported modes.
This patch adds a workaround for WM_STYLECHANGED messages that are not
delivered when running on Mono/Windows. If we detect Mono, then we call
HandleStyleChanged() directly in order to update the internal state of
our WinGLNative instance.
OpenTK now directly calculates the elapsed time between UpdateFrame
(RenderFrame) events and compares that directly to TargetUpdatePeriod
(TargetRenderPeriod). This significantly simplifies the implementation
and improves timing stability.
PlatformFactoryBase provides a common base interface for platform
backends. Platform backends should inherit from PlatformFactoryBase in
order to reduce code duplication.
LegacyJoystickDriver implements the legacy IJoystickDriver interface
(GameWindow.Joysticks) in terms of the new IJoystickDriver2 interface
(OpenTK.Input.Joystick).
This removes a large chunk of code from each platform backend, as they
no longer need to implement IJoystickDriver themselves. Additionally,
it adds support for device hot plugging which was previously missing.
This patch modifies GameWindow.Run() to use a single stopwatch instead
of two separate stopwatches for timing UpdateFrame and RenderFrame
events.
It improves timing accuracy for issue #20 (FrameEventArgs.Time
Inconsistencies)
DeviceAdded already checks that devices conform to the desired usage
pages. Checking again in DeviceRemoved is unnecessary - if a device
exists, then it has already passed muster.
JoystickAxis/Button.Last is used internally to allocate the correct
amount of storage for joystick axes and buttons. JoystickAxis.Axis10 is
required to support the maximum number of axes available on Mac OS X.
SDL2 uses a weird system of device ids and instance ids to report
joystick events, where the ADDED event uses a device id and the rest use
instance ids.
The SDL2 joystick driver is now fixed to correctly distinguish between
the two, which fixes hotplugging support for joystick devices.
SDL GameControllerAxis and GamePadAxes are not interchangeable. The
driver will now correctly interpret incoming SDL messages and update
the GamePadState for the relevant axis.
GamePadState.SetAxis() receives a GamePadAxes enumeration, which is a
bitmask of the axes we wish to set. SetAxis now correctly decodes the
bitmask to apply the values we are interested in.
This test uses SDL2 to create a window and an OpenGL context. It then
uses OpenTK to render into the external SDL2 context. If everything is
working correctly, a black window should appear and gradually turn
white before disappearing.
When combining OpenTK with a third-party OpenGL toolkit, it is now
possible to implement a suitable GetAddress() and GetCurrentContext()
implementation in terms of the third-party toolkit. If no
implementation is specified, then OpenTK will try to guess the most
suitable implementation within its own platform backends.
If no custom implementation is defined, and if no suitable
implementation can be found, then OpenTK will throw a
PlatformNotSupportedException. If a suitable implementation is found or
defined, then OpenTK will attempt to load OpenGL entry points using
that implementation.
In this case third-party toolkit remains solely responsible for
managing its context via its MakeCurrent(), SwapBuffers(), etc
implementations.
DummyGLContext will now attempt to load OpenGL and OpenGL ES entry
points when a suitable OpenGL context is current on the calling thread.
This allows OpenTK to be used on contexts created through third-party
toolkits.
CreateGetAddress() constructs a GraphicsContext.GetAddressDelegate that
is suitable for the current platform. This can be used when combining
OpenTK with an OpenGL context created through a third-party toolkit.
The functions defined in libdl.dylib are useful in more places than
just AglContext. Moving them to their own class ensures we can access
these from wherever we might need them.
CGL appears to work with both AGL and NSOpenGL contexts, whereas AGL is
limited to AGL contexts. This allows us to be more flexible in terms of
implementation (i.e. we can use Cgl.GetCurrentContext to retrieve a
handle to a context created through SDL, which uses NSOpenGL
internally.)
When the user requests a GraphicsMode that is not directly supported
by the GPU/drivers, we should relax the requested parameters until
we find a supported mode. An exception should only be thrown when
there is no usable mode.
This makes the X11 backend match the behavior of Windows. The SDL/X11
backend works a little bit differently, in that it falls back to the
a default mode directly if the requested mode is not available. There
is nothing we can do about that.
The _NET_FRAME_EXTENTS atom is implemented differently by
different window managers, when window decorations are hidden
with Motif. Unity returns a 0 size, while Gnome 3 returns the
previous size.
This patch removes that ambiguity: when decorations are hidden,
border size becomes zero. This should work everywhere, unless
some window manager decides to troll us by decorating the window
when we explicitly request no decorations. Sigh...
Windows can now be resized programmatically, even when they have
WindowBorder.Fixed. All resizing logic is now consolidated in the
Bounds property, and ConfigureNotify messages are now handled
correctly depending on their source (StructureNotify or
SubStructureNotify.)
WinMM is optimized for general joystick use, not for the canonical
GamePad layout. Instead of exposing IGamePadDriver directly, it should
expose IJoystickDriver2 and use a mapping driver to get GamePad support.
GraphicsMode.Index is set by the platform-specific context constructor,
which is invoked after the X11GLControl constructor. It does not make
sense to check GraphicsMode.Index in the X11GLControl constructor, as it
is never set at that point.
Without this flag, OpenGL rendering does not work as expected.
Additionally, all WGL_ARB_pixel_format attributes are expected to be
specified in key-value pairs. Fixed double-buffering and stereoscoping
rendering attributes.
Fixed WGL_ARB_pixel_format attribute selection for doublebuffering,
stereoscopic rendering and hardware acceleration. Implemented
minimization strategy to select the optimal PixelFormatDescriptor in the
fallback path.
Instead of creating a list of all available formats and iterating
through that, we let the driver decide which is the best accelerated
format to use for the user parameters. If no such format exists, we fall
back to generic acceleration or software acceleration, in turn.
This affects issue #21
Starting with OpenGL 4.2, strings passed to GL.ShaderSource are allowed
to contain multi-byte characters in comments (issue #18). This patch
modifies the marshaling code to use UTF8.GetBytes in order to marshal
strings, instead of Marshal.StringToHGlobalAnsi().
Don't filter window messages passed to our window (see
http://blogs.msdn.com/b/oldnewthing/archive/2005/02/09/369804.aspx).
Additionally, return the correct values for all messages we are actually
handling and clean up unmanaged memory after we are done with the
window.
Instead of combining PeekMessage+GetMessage, we can simply call
PeekMessage(Remove) to achieve the same effect. This also allows us to
remove the IsIdle property, which is no longer used anywhere.
The temporary context is now retained until the actual context has been
constructed. If we don't do this, then WGL_ARB_create_context may fail
to work correctly on specific GPUs (e.g. Intel). This may affect issue
#19.
The correct way to query number of available pixel formats is to use
Wgl.Arb.GetPixelFormatAttrib(NumberPixelFormatsArb), not
Wgl.Arb.ChoosePixelFormats. This fixes an issue where Intel drivers
would fail to report any pixel formats in GetModesARB, even when
WGL_ARB_pixel_format is supported.
On many/most platforms, GraphicsContexts can only be released by the
thread where they are current. This means that the user must call
GraphicsContext.Dispose() or risk a resource leak.
Since we cannot release contexts on the finalizer thread, we should keep
strong references, instead of weak references, until the user explicitly
calls Dispose().
This patch fixes issues with SDL2 crashing when running the MonoGame
WindowsGL test suite.