Installation

To get started with OpenTK you are probably going to need an IDE (Intergrated Development Environment) which serves as an editor and keeps track of include files (or assemblies as they're called). Essentially this will be MonoDevelop or Visual Studio. There is more information in the official documentation. I am using Visual Studio and doing cross platform testing with Ubuntu.

To make sure things are working right, try this

using System;
using System.IO;
 
class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Hello World!");
    Console.WriteLine("This is a C# console application.");
  }
}

On Windows the executable HelloWorld.exe runs immediately by double clicking on the file. On Ubuntu you must execute using

mono HelloWorld.exe

This program should run without recompilation on any platform equipped with Mono or .NET.

You are also probably going to need a GUI. Both Microsoft and Mono offer more than one set of libraries. I am partial to Windows Forms because I'm windows-centric, but GTK is very good and I like it too. Here is a GUI sample

using System;
using System.Windows.Forms;
 
public class HelloWorld : Form
{
  static public void Main()
  {
    Application.Run(new HelloWorld());
  }
 
  public HelloWorld()
  {
    Text = "Hello World";
  }
}

This one ran immediately on Windows. I had to tell Ubuntu to download the Windows Forms package from the Mono depository, then the example worked perfectly.

Now that your IDE is working, you need to install OpenTK. I downloaded a file called opentk-0.9.9-3.zip and expanded it to C:\. Installation very easy. Just tell Visual Studio to use the assembly

C:\opentk-0.9.9-3\Binaries\OpenTK\Release\OpenTK.dll

This is explained in detail in the official documentation.

Now we want to see whether this works at all. Here's the sample code:

using System;
using System.IO;
 
using OpenTK;
 
namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      var devices = OpenTK.DisplayDevice.AvailableDisplays;
      foreach (var device in OpenTK.DisplayDevice.AvailableDisplays)
      {
        Console.WriteLine(device);
      }
    }
  }
}

Yes. It gives the correct output

Primary: {X=0,Y=0,Width=1920,Height=1200}x32@60Hz (41 modes available)
Press any key to continue . . .

You will notice that the official documentation is completely messed up on these function calls. [Fixed now, see note below.] In general the best way to sort these things out is to take a look at the source code which is quite well organized and easy to read. You can find that here

C:\opentk-0.9.9-3\Source\OpenTK

I was lucky and noticed the DisplayDevice class immediately.

Now I will pause here to check this on Ubuntu.

I copied the executable and OpenTK.dll to my Ubuntu system. It worked perfectly. My laptop actually has more video modes than my desktop.

Next step is setting up an OpenGL sample window.


Comments

Comment viewing options

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

Updated and simplified documentation to match the 0.9.9-3 release.

VeliV's picture

This is great stuff for a noob like me ;) I'm waiting for the next part of the tutorial, since I need to implement a OpenGL inside a window.

Oh, just a minor note. Could you show how to get GLControl run in a application like this?

using System;
using System.Windows.Forms;
 
public class HelloWorld : Form
{
  static public void Main()
  {
    Application.Run(new HelloWorld());
  }
 
  public HelloWorld()
  {
    Text = "Hello World";
  }
}

I tired out the other tutorial on this subject, but since I am on OSX I couldn't add the glControl as a component to the form (the first part of tutorial).

the Fiddler's picture

Just add the GLControl as a class field:

using System;
using System.Windows.Forms;
 
public class HelloWorld : Form
{
  GLControl glControl = new GLControl();
 
  static public void Main()
  {
    Application.Run(new HelloWorld());
  }
 
  public HelloWorld()
  {
    Text = "Hello World";
 
    glControl.Dock = DockStyle.Fill; // I hope I got this right     
    glControl.Paint += (sender, e) =>
    {
       glControl.SwapBuffers();
    };
    Controls.Add(glControl);
  }
}

Of course, you can modify the control's size, dockstyle, anchoring, name, vsync and anything else you'd like. (The simplest approach is to add a glControl.Dock = DockStyle.Fill; so that it covers the whole form).

VeliV's picture

Fiddler, that code you pasted doesnt seem to work. It complains about GLControl namespace not being found and when I fix it like this:

using System;
using System.Windows.Forms;
 
public class HelloWorld : Form
{
  OpenTK.GLControl glControl = new OpenTK.GLControl();
 
  static public void Main()
  {
    Application.Run(new HelloWorld());
  }
 
  public HelloWorld()
  {
    Text = "Hello World";
 
    glControl.Dock = DockStyle.Fill; // I hope I got this right     
    glControl.Paint += (sender, e) =>
    {
       glControl.SwapBuffers();
    };
    Controls.Add(glControl);
  }
}

Which i think should be correct, it just flashes the window and crashes with the following output:

System.InvalidCastException: Cannot cast from source type to destination type.
  at OpenTK.Platform.MacOS.AglContext..ctor (OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext) [0x00000] 
  at OpenTK.Platform.MacOS.MacOSFactory.CreateGLContext (OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, Boolean directRendering, Int32 major, Int32 minor, GraphicsContextFlags flags) [0x00000] 
  at OpenTK.Graphics.GraphicsContext..ctor (OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, Int32 major, Int32 minor, GraphicsContextFlags flags) [0x00000] 
  at OpenTK.CarbonGLControl.CreateContext (Int32 major, Int32 minor, GraphicsContextFlags flags) [0x00000] 
  at OpenTK.GLControl.OnHandleCreated (System.EventArgs e) [0x00000] 
  at System.Windows.Forms.Control.WmCreate (System.Windows.Forms.Message& m) [0x00000] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs:5759 
  at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message& m) [0x001e4] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs:5397 
  at System.Windows.Forms.ScrollableControl.WndProc (System.Windows.Forms.Message& m) [0x00000] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ScrollableControl.cs:807 
  at System.Windows.Forms.ContainerControl.WndProc (System.Windows.Forms.Message& m) [0x0003d] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs:642 
  at System.Windows.Forms.UserControl.WndProc (System.Windows.Forms.Message& m) [0x00037] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/UserControl.cs:150 
  at System.Windows.Forms.Control+ControlWindowTarget.OnMessage (System.Windows.Forms.Message& m) [0x00000] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs:234 
  at System.Windows.Forms.Control+ControlNativeWindow.WndProc (System.Windows.Forms.Message& m) [0x00000] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs:215 
  at System.Windows.Forms.NativeWindow.WndProc (IntPtr hWnd, Msg msg, IntPtr wParam, IntPtr lParam) [0x00085] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NativeWindow.cs:242

Using Snow Leopard and the latest versions of Mono and OpenTK :)

the Fiddler's picture

VeliV, I'd suggest creating a new bug report for this issue. I just committed a fix, but I cannot actually test that GLControl is now working correctly.

It would really help if you could install a subversion client and test with OpenTK from SVN.

VeliV's picture

Yah, had some problems with subversion, since the solution and project files aren't included in it (couldn't open the project in mono). But I managed around it.

But it still crashes. Here is the output:

System.InvalidCastException: Cannot cast from source type to destination type.
  at OpenTK.Platform.MacOS.AglContext..ctor (OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext) [0x00000] 
  at OpenTK.Platform.MacOS.MacOSFactory.CreateGLContext (OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, Boolean directRendering, Int32 major, Int32 minor, GraphicsContextFlags flags) [0x00000] 
  at OpenTK.Graphics.GraphicsContext..ctor (OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, Int32 major, Int32 minor, GraphicsContextFlags flags) [0x00000] 
  at OpenTK.CarbonGLControl.CreateContext (Int32 major, Int32 minor, GraphicsContextFlags flags) [0x00000] 
  at OpenTK.GLControl.OnHandleCreated (System.EventArgs e) [0x00000] 
  at System.Windows.Forms.Control.WmCreate (System.Windows.Forms.Message& m) [0x00000] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs:5759 
  at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message& m) [0x001e4] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs:5397 
  at System.Windows.Forms.ScrollableControl.WndProc (System.Windows.Forms.Message& m) [0x00000] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ScrollableControl.cs:807 
  at System.Windows.Forms.ContainerControl.WndProc (System.Windows.Forms.Message& m) [0x0003d] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs:642 
  at System.Windows.Forms.UserControl.WndProc (System.Windows.Forms.Message& m) [0x00037] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/UserControl.cs:150 
  at System.Windows.Forms.Control+ControlWindowTarget.OnMessage (System.Windows.Forms.Message& m) [0x00000] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs:234 
  at System.Windows.Forms.Control+ControlNativeWindow.WndProc (System.Windows.Forms.Message& m) [0x00000] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs:215 
  at System.Windows.Forms.NativeWindow.WndProc (IntPtr hWnd, Msg msg, IntPtr wParam, IntPtr lParam) [0x00085] in /private/tmp/monobuild/build/BUILD/mono-2.4.2.3/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NativeWindow.cs:242

I'll go add an issue, altough I am not really sure what to put in it :D

the Fiddler's picture

The stack trace should be enough.

You can generate the missing project files by running Build.exe from a terminal ("mono Build.exe", just press enter). Build the debug version of OpenTK (so that the stack trace will include line numbers) and replace the OpenTK reference in your project with the new one (assembly version should read 0.9.9-4). You might have to remove the current reference before adding the new one to make this work.

If it still crashes, please post the new stack trace, which will contain line numbers instead of [0x00000] values.

VeliV's picture

I feel quite dumb for asking this, but how do I draw something in it? :P I got stuff working in GameWindow, but I don't know where to put the GL commands with GLControl :)

AdrianPi's picture

Add a paint event handler after creating the GLControl:

glControl1.Paint += new System.Windows.Forms.PaintEventHandler(this.glControl1_Paint);

And then add your OpenGL commands there:

private void glControl1_Paint(object sender, PaintEventArgs e)
{
    GL.ClearColor(0, 0, 0.5f, 1);
    GL.Viewport(0, 0, glControl.Width, glControl1.Height);
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
    // more drawing code here....
 
    glControl1.SwapBuffers();
}
VeliV's picture

Thanks, works now.