C#使用OpenTK绘制一个着色矩形

news/2025/1/12 6:44:36/

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;}}
}

程序运行如图:


http://www.ppmy.cn/news/1562430.html

相关文章

DDD - 如何运用 DDD 进行数据库设计

文章目录 Pre概述领域对象持久化的思想领域模型的设计传统的 4 种关系1. 一对一关系2. 多对一关系3. 一对多关系4. 多对多关系 继承关系的 3 种设计1. 继承关系的第一种方案&#xff1a;整个父类与子类都写入一张表2. 继承关系的第二种方案&#xff1a;各子类各自对应各自的表3…

分享:osgb倾斜数据转cesium-3dtiles 小工具.

背景: 很多知识殊途同归,在三维软件这块,少不了要和各种各样的数据格式打交道.osgb,stl,obj,3dtiles,3ds等等..虽然里面本质核心基本都是几何数据拓扑数据材质纹理数据等等,但是由于其组织方式不同和特殊的应用场景,导致很多模型需要转来转去...相信很多人在这方面都或多或少吃…

记录一下vue2项目优化,虚拟列表vue-virtual-scroll-list处理10万条数据

文章目录 封装BrandPickerVirtual.vue组件页面使用组件属性 select下拉接口一次性返回10万条数据&#xff0c;页面卡死&#xff0c;如何优化&#xff1f;&#xff1f;这里使用 分页 虚拟列表&#xff08;vue-virtual-scroll-list&#xff09;&#xff0c;去模拟一个下拉的内容…

本地缓存:Guava Cache

这里写目录标题 一、范例二、应用场景三、加载1、CacheLoader2、Callable3、显式插入 四、过期策略1、基于容量的过期策略2、基于时间的过期策略3、基于引用的过期策略 五、显示清除六、移除监听器六、清理什么时候发生七、刷新八、支持更新锁定能力 一、范例 LoadingCache<…

计算机网络之---传输层的功能

传输层的功能 传输层是 OSI&#xff08;开放系统互联&#xff09;七层模型中的第四层&#xff0c;位于应用层和网络层之间。传输层的主要作用是提供端到端的通信服务&#xff0c;确保数据在不同设备之间的可靠传输。它主要负责将来自上层&#xff08;应用层&#xff09;的数据拆…

spring mvc源码学习笔记之九

在前面的文章中&#xff0c;我们简单讲了可以用 WebApplicationInitializer 接口去替换 web.xml。 本文对这一块再做个详细讲解。 在 WebApplicationInitializer 这个接口的 javadoc 中有提到可以用继承 AbstractAnnotationConfigDispatcherServletInitializer 的方式替换实现 …

LeetCode 2765. 最长交替子数组解析与解题思路

LeetCode 2765. 最长交替子数组解析与解题思路 在本篇博客中&#xff0c;我们将深入解析 LeetCode 上的一道有趣题目 —— 2765. 最长交替子数组。我们将通过题目理解、解题思路、代码实现以及示例解析&#xff0c;全面掌握这道题目的解决方法。 题目描述 给定一个下标从 0 …

网站运营数据pv、uv、ip

想要彻底弄清楚pv uv ip的区别&#xff0c;首先要知道三者的定义&#xff1a; IP(独立IP)的定义&#xff1a; 即Internet Protocol,指独立IP数。24小时内相同公网IP地址只被计算一次。 PV(访问量)的定义&#xff1a; 即Page View,即页面浏览量或点击量&#xff0c;用户每次刷…