Question

I'm getting a NotImplementedException in version 1.1 (stable release), the source has been included in the program, and not compiled to OpenTK.dll (single file app) without resources.

I have done this before but not with version 1.1:

public GameWindow(int width, int height, GraphicsMode mode, string title, GameWindowFlags options, DisplayDevice device,
                      int major, int minor, GraphicsContextFlags flags, IGraphicsContext sharedContext)
        : base(width, height, title, options,
               mode == null ? GraphicsMode.Default : mode,
               device == null ? DisplayDevice.Default : device)
    {
        try
        {
            glContext = new GraphicsContext(mode == null ? GraphicsMode.Default : mode, WindowInfo, major, minor, flags);
            glContext.MakeCurrent(WindowInfo);
            (glContext as IGraphicsContextInternal).LoadAll();

            VSync = VSyncMode.On;

            //glWindow.WindowInfoChanged += delegate(object sender, EventArgs e) { OnWindowInfoChangedInternal(e); };
        }
        catch (Exception e)
        {
            Debug.Print(e.ToString());
            base.Dispose();
            throw;
        }
    }

Is there a way around this? Some sources indicate that it's a linker issue, that the toolkit library is being modified after the build. In short, can it be fixed, or should I revert to an older version (which seems unattractive)?

Was it helpful?

Solution

Indeed, OpenTK 1.1 includes a new binding mechanism based on 'calli' instructions, which are not available in regular C#. The advantage is that they allow us to improve performance and lower memory consumption compared to using delegates or DllImports. (OpenTK 1.1 is consuming 500KB of memory in 5K objets, compared to 1500KB in 30K objects in OpenTK 1.0.)

The downside, of course, is that we need to post-process OpenTK.dll as a post-build event. This is not an issue if you are using a precompiled binary or compiling OpenTK.dll from source, but it makes it more complicated if you include the .cs files directly into your project.

Three solutions, in order of preference:

  1. Instead of including the .cs files in your project, use ilmerge or ilrepack to embed the compiled OpenTK.dll into your executable. As a bonus, you can use the monolinker to reduce size by an order of magnitude (see below).
  2. Include the .cs files and run Generator.Rewrite as a post-build event. The rewriter will only touch code marked with as [AutoGenerated], so your code should be safe. Adding a post-build event takes some effort and will slightly increase your build times, but it's still a viable option.
  3. Revert to OpenTK 1.0.

Depending on why you are embedding the .cs files in your project, some approaches might make more sense than others. I personally follow approach #1, as it is by far the simplest and most versatile option:

  • Upgrading for newer OpenGL APIs becomes a breeze (use nuget or copy the new dll manually)
  • monolinker reduces OpenTK.dll down to 190-550KB depending on the features I am using. For comparison, OpenTK 1.0 is 2900KB and OpenTK 1.1 is 3800KB.

A copy of monolinker is included in the OpenTK downloads if you need it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top