OpenTK介绍
OpenTK是一个开源、跨平台的游戏开发库,由MonoGame团队创建。它为C#开发者提供了一个简单易用的接口,以便使用OpenGL、OpenAL和OpenCL进行3D渲染、音频处理和并行计算。OpenTK的目标是提供一个一致且高效的框架,让开发者能够专注于构建他们的游戏和图形应用程序,而无需担心底层硬件和操作系统之间的差异。
此外,OpenTK是一个对OpenGL、OpenAL、OpenCL的跨平台封装,使用C#编写,可以运行在Windows、Linux以及MacOSX平台上,任何.Net语言都可以使用它进行开发。OpenTK具有快速开发的特点,它使用.Net的强类型和内嵌的注释文档,有助于提高代码流程,并且有助于快速发现错误。同时,OpenTK也可以单独使用,或者无缝集成到Windows Forms、WPF或GTK#等其它应用程序中。
总的来说,OpenTK是一个功能强大的跨平台游戏开发库,为C#开发者提供了便捷的开发接口和工具,使得开发者能够更加专注于游戏和图形应用程序的构建,提高了开发效率和便捷性。
OpenTK 和 OpenGL 区别。
OpenGL 是一种跨平台的图形渲染 API,用于创建 2D 和 3D 图形。它由 Khronos Group 组织维护,并支持多种编程语言和平台。OpenGL 提供了一组用于绘制图形的函数和数据类型,它们可以用于创建各种各样的图形效果,如模拟光照、纹理映射、变换等等。
OpenTK 是一个开源的跨平台的 .NET 绑定库,它提供了一组 C# 接口,用于访问 OpenGL 等底层图形 API。OpenTK 可以让 .NET 开发人员使用 C# 语言编写图形应用程序,而无需依赖于底层的 OpenGL API。
因此,可以说 OpenTK 是 OpenGL 的一个封装库,它封装了 OpenGL 的底层实现,提供了更加易用的 C# 接口。如果你使用 OpenTK,你可以使用 C# 编写 OpenGL 应用程序,而无需了解 OpenGL 的底层实现细节。
以下演示使用OpenTK框架绘制一个着色矩形,
矩形为OpenTK.Graphics.OpenGL.PrimitiveType.Quads
新建Winform应用程序OpenTKDemo,将默认的Form1重命名为FormOpenTK_GLControl
注意在WindowsForm应用程序中,需要使用框架OpenTK.GLControl
因使用.net framework4..6.1版本,没有使用.net core,这里选择OpenTK较低版本3.3.3
管理Nuget包,输入关键字OpenTK
点击安装
安装完后
窗体FormOpenTK_GLControl设计器代码如下:
文件FormOpenTK_GLControl.Designer.cs
using OpenTK;namespace OpenTKDemo
{partial class FormOpenTK_GLControl{/// <summary>/// 必需的设计器变量。/// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// 清理所有正在使用的资源。/// </summary>/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows 窗体设计器生成的代码/// <summary>/// 设计器支持所需的方法 - 不要修改/// 使用代码编辑器修改此方法的内容。/// </summary>private void InitializeComponent(){this.SuspendLayout();// // FormOpenTK_GLControl// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(800, 450);this.Name = "FormOpenTK_GLControl";this.Text = "WindowsForm应用程序需要使用OpenTK.GLControl框架";this.Load += new System.EventHandler(this.FormOpenTK_GLControl_Load);this.ResumeLayout(false);}#endregion}
}
窗体 FormOpenTK_GLControl绘制矩形相关程序如下:
文件FormOpenTK_GLControl.cs
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace OpenTKDemo
{public partial class FormOpenTK_GLControl : Form{private static GameWindow gameWindow;private static int _vao;private static int _vbo;private static int _shaderProgram;public FormOpenTK_GLControl(){InitializeComponent();}private void FormOpenTK_GLControl_Load(object sender, EventArgs e){using (gameWindow = new GameWindow(960, 720, GraphicsMode.Default, title: "OpenTK 斯内科")){gameWindow.Load += GameWindow_Load;gameWindow.RenderFrame += GameWindow_RenderFrame;gameWindow.Run();}//Vector2}private void GameWindow_RenderFrame(object sender, FrameEventArgs e){//图形渲染// 清屏【红绿蓝都为1为白色,都为0为黑色】GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f);GL.Clear(ClearBufferMask.ColorBufferBit);// 使用着色器并绘制矩形GL.UseProgram(_shaderProgram);GL.BindVertexArray(_vao);GL.DrawArrays(PrimitiveType.Quads, 0, 4);// 交换缓冲区gameWindow?.SwapBuffers();}private void GameWindow_Load(object sender, EventArgs e){// 顶点数据:矩形的顶点位置和颜色// 【数学中的X0Y坐标系【屏幕中心为原点,X轴向右,Y轴向上】,这个与Winform的坐标系【左上角为原点,X轴向右,Y轴向下】不同】float[] vertices = {// Positions // Colors -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, // 顶点2:红色(位置x,y,颜色r,g,b,a)0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, // 顶点1:红色0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 顶点3:绿色-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f // 顶点4:蓝色};//顶点数组对象(VAO)和顶点缓冲对象(VBO)// 创建并绑定 VAO:Vertex Array Object_vao = GL.GenVertexArray();GL.BindVertexArray(_vao);// 创建并绑定 VBO:Vertex Buffer Object_vbo = GL.GenBuffer();GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo);GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);// 创建和编译着色器_shaderProgram = CreateShaderProgram();// 设置顶点属性指针GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);GL.EnableVertexAttribArray(0);GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float));GL.EnableVertexAttribArray(1);}private static int CreateShaderProgram(){// 顶点着色器代码string vertexShaderSource = @"#version 330 corelayout(location = 0) in vec3 aPosition;layout(location = 1) in vec3 aColor;out vec3 vColor;void main(){vColor = aColor;gl_Position = vec4(aPosition, 1.0);}";// 片段着色器代码string fragmentShaderSource = @"#version 330 corein vec3 vColor;out vec4 FragColor;void main(){FragColor = vec4(vColor, 1.0);}";// 创建和编译着色器int vertexShader = CompileShader(ShaderType.VertexShader, vertexShaderSource);int fragmentShader = CompileShader(ShaderType.FragmentShader, fragmentShaderSource);// 链接着色器程序int program = GL.CreateProgram();GL.AttachShader(program, vertexShader);GL.AttachShader(program, fragmentShader);GL.LinkProgram(program);// 检查链接错误GL.GetProgram(program, GetProgramParameterName.LinkStatus, out int success);if (success == 0){GL.GetProgramInfoLog(program, out string info);throw new Exception($"Shader linking failed: {info}");}// 删除着色器GL.DeleteShader(vertexShader);GL.DeleteShader(fragmentShader);return program;}private static int CompileShader(ShaderType type, string source){int shader = GL.CreateShader(type);GL.ShaderSource(shader, source);GL.CompileShader(shader);// 检查编译错误GL.GetShader(shader, ShaderParameter.CompileStatus, out int success);if (success == 0){GL.GetShaderInfoLog(shader, out string info);throw new Exception($"{type} compilation failed: {info}");}return shader;}}
}