OpenTK on .Net Core
On November 30, 2020 by nigel@apeindex.rocksFollowing through the example on the OpenTK site came up with a lot of compiler errors. Here is the extra information required to get up and running with the example.
To begin, install Open TK by opening the NuGet package manager: Visual Studio > Tools > NuGet Package Manager > Package Manger Console
At the prompt, type
PM> Install-Package OpenTK
Create a new Console application in C# on .Net Core to keep it simple. I called mine OpenTKTest1
The first hurdle I came across was that many of the classes were missing and I had to add in a few extra using statements
using System; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; using OpenTK.Input; using OpenTK.Windowing.Desktop; using OpenTK.Windowing.Common; using OpenTK.Mathematics;
Even creating the GameWindow had moved on from the example
namespace OpenTKTest1 { class Game : GameWindow { public Game(GameWindowSettings g, NativeWindowSettings n) : base(g,n) { VSync = VSyncMode.On; } protected override void OnLoad() { Title = "Test OpenTK!"; base.OnLoad(); } protected override void OnResize(ResizeEventArgs e) { base.OnResize(e); GL.Viewport(0, 0, e.Width, e.Height); } [STAThread] static void Main() { GameWindowSettings gws = new GameWindowSettings(); NativeWindowSettings nws = new NativeWindowSettings(); gws.UpdateFrequency = 30; gws.RenderFrequency = 30; nws.Size = new OpenTK.Mathematics.Vector2i(800, 600); nws.StartVisible = true; nws.Title = "Test game"; nws.WindowState = OpenTK.Windowing.Common.WindowState.Normal; using (Game game = new Game(gws,nws)) { game.Run(); } } } }
Most of the rest of the example was OK. I couldn’t understand a few lines, such as GL.UseProgram(); and Exit(); which I commented out and it ran OK. I couldn’t press the Escape key to exit but felt that was a minor point, and I wasn’t sure how to set the screen refresh rate to unlimited.
Here’s a link to the original learning 101 page
https://opentk.net/learn/chapter1/2-hello-triangle.html
I got a few clues from the following link
https://neokabuto.blogspot.com/2013/02/opentk-tutorial-1-opening-windows-and.html
and when you need a control on a form, here are some clues
https://stackoverflow.com/questions/59977236/showing-opentk-glcontrol-in-winforms
Finally, a full listing of the code which is quite a trial to piece together from the learning resource.
using System; using System.Collections.Generic; using System.IO; using System.Text; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace OpenTKTest1 { public class Shader { int Handle; string VertexShaderSource; int VertexShader; int FragmentShader; public Shader(string vertexPath, string fragmentPath) { using (StreamReader reader = new StreamReader(vertexPath, Encoding.UTF8)) { VertexShaderSource = reader.ReadToEnd(); } string FragmentShaderSource; using (StreamReader reader = new StreamReader(fragmentPath, Encoding.UTF8)) { FragmentShaderSource = reader.ReadToEnd(); } VertexShader = GL.CreateShader(ShaderType.VertexShader); GL.ShaderSource(VertexShader, VertexShaderSource); FragmentShader = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(FragmentShader, FragmentShaderSource); GL.CompileShader(VertexShader); string infoLogVert = GL.GetShaderInfoLog(VertexShader); if (infoLogVert != System.String.Empty) System.Console.WriteLine(infoLogVert); GL.CompileShader(FragmentShader); string infoLogFrag = GL.GetShaderInfoLog(FragmentShader); if (infoLogFrag != System.String.Empty) System.Console.WriteLine(infoLogFrag); Handle = GL.CreateProgram(); GL.AttachShader(Handle, VertexShader); GL.AttachShader(Handle, FragmentShader); GL.LinkProgram(Handle); GL.DetachShader(Handle, VertexShader); GL.DetachShader(Handle, FragmentShader); GL.DeleteShader(FragmentShader); GL.DeleteShader(VertexShader); } public void Use() { GL.UseProgram(Handle); } private bool disposedValue = false; protected virtual void Dispose(bool disposing) { if (!disposedValue) { GL.DeleteProgram(Handle); disposedValue = true; } } ~Shader() { GL.DeleteProgram(Handle); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } }
You will still need the shader code and filenames from the example to bundle it all together, and set them in visual studio to copy to the compiled output location so that GL can compile them on demand.

// shader.frag - must be copied to output folder #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); }
// shader.vert - must be copied to output folder #version 330 core layout (location = 0) in vec3 aPosition; void main() { gl_Position = vec4(aPosition, 1.0); }
Calendar
M | T | W | T | F | S | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 |
Leave a Reply