Kiena's picture

NativeWindow factory

Would it be possible to add a public factory class that could return objects implementing INativeWindow or would that contradict something in the library design?

It would trivially be something like:

using OpenTK.Graphics;
using OpenTK.Platform;
 
namespace OpenTK
{
    public sealed class NativeWindowFactory
    {
        // Note: No Rectangle please, it's not really necessary in the 0.9.9-1 version of the GameWindow constructor, either.
        public static INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
        {
            // TODO: Argument checking.
            return Platform.Factory.Default.CreateNativeWindow(x, y, width, height, title, mode, options, device);
        }
    }
}

This would allow development of classes like GameWindow with different timing and/or threading models, for example.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
objarni's picture

What is the difference between Platform.Factory.Default.CreateNativeWindow(..) and NativeWindowFactory.CreateNativeWindow(..)?

Kiena's picture

The Factory class in the Platform namespace is visible only in the assembly.

the Fiddler's picture

Assuming you don't mind constructing the IGraphicsContext, you can create a regular GameWindow and override its Run method to implement a different timing model. If there is a legitimate reason to have a "naked" INativeWindow implementation, I think the best solution would be to add a public NativeWindow class and modify the current GameWindow to inherit from that.

What do you mean by different "threading models"? If you are refering to moving input to a different thread, this is already in progress (see #969: [Input] Add static classes for Mouse, Keyboard and GamePad input). It should also be possible to move UpdateFrame and RenderFrame into different threads, if you wish (just override Run()). However, all other INativeWindow events (Resize, etc) can only be generated on the thread that constructed the window (this is an OS limitation).

Kiena's picture

I didn't even think of doing operations actually related to on-screen rendering on multiple threads, I heard enough bad things about others' attempts. So my intention would be to separate the logic/state and input processing from them, as you assumed. Is ProcessEvents also among those NativeWindow methods that must occur on the same thread in the current version?

The actual difference would be that no hacking would be needed to ignore and/or work around the provided structure.

Creation of the context would be part of a custom implementation, of course, but why would that be necessary in the overriding scenario? There is a way to obtain the one created in the constructor, and that would allow to make it current on another thread. (Letting the rendering occur in the main thread would be fine for me, actually.)

Despite the possibly cleaner code, thanks for the suggestion, and I may go this way if no one else would need access to raw NativeWindows.

About the timing:
(Assuming I'm right, and GameWindow's timing isn't actually related to vertical synchronization handling, thuschanging it wouldn't matter.)
I would rather go with a (potentially fake, actually lower resolution, depending on Stopwatch.IsHighResolution) nanosecond timing, without any Stopwatch objects. The static timestamp and constant frequency seems sufficient. So no stopping, resetting and TimeSpans allocated, and integral values instead of floating point ones.

the Fiddler's picture

Yes, ProcessEvents must run on the main thread. Since input is handled inside ProcessEvents, input events must also originate from that thread - hence the input system redesign.

Overriding the Run method will allow you to implement custom timing loops. The exact implementation does not matter, so feel free to implement timing any way you'd like.

(As an aside, TimeSpans are allocated on the stack, so they do not carry a performance penalty.)

Kiena's picture

Input redesign would definitely affect custom classes too, but one more reason against non-conforming inheritance is possible later breaking internal changes. Anyway, if it ever comes to that I would happily help out with not platform specific matters (EDIT: The sources included in the release compiled fine (514 warnings on windows), so the uncertainty remaining is any external tool needed if I checked the sources out from the repository).