当前位置: 首页 > news >正文

C#使用OpenTK绘制3D可拖动旋转图形三棱锥

接上篇,绘制着色矩形

C#使用OpenTK绘制一个着色矩形-CSDN博客

上一篇安装OpenTK.GLControl后,这里可以直接拖动控件GLControl

我们会发现GLControl继承于UserControl

    //// 摘要://     OpenGL-aware WinForms control. The WinForms designer will always call the default//     constructor. Inherit from this class and call one of its specialized constructors//     to enable antialiasing or custom OpenTK.GLControl.GraphicsModes.public class GLControl : System.Windows.Forms.UserControl

以下我们绘制一个三棱锥,三棱锥需要四个顶点Vertex

新建窗体FormGLControl,拖入一个控件GLControl,绑定Load,Paint等事件

窗体FormGLControl设计器代码为:

文件FormGLControl.Designer.cs

using OpenTK;
namespace OpenTKDemo
{partial class FormGLControl{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){this.glControl1 = new OpenTK.GLControl();this.SuspendLayout();// // glControl1// this.glControl1.BackColor = System.Drawing.Color.Black;this.glControl1.Location = new System.Drawing.Point(12, 12);this.glControl1.Name = "glControl1";this.glControl1.Size = new System.Drawing.Size(800, 600);this.glControl1.TabIndex = 0;this.glControl1.VSync = false;this.glControl1.Load += new System.EventHandler(this.glControl1_Load);this.glControl1.Paint += new System.Windows.Forms.PaintEventHandler(this.glControl1_Paint);this.glControl1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseDown);this.glControl1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseMove);this.glControl1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseUp);this.glControl1.Resize += new System.EventHandler(this.glControl1_Resize);// // FormGLControl// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(832, 619);this.Controls.Add(this.glControl1);this.Name = "FormGLControl";this.Text = "FormGLControl";this.ResumeLayout(false);}#endregionprivate GLControl glControl1;}
}

窗体FormGLControl相关代码如下:

文件FormGLControl.cs

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;
using OpenTK;
using OpenTK.Graphics.OpenGL;namespace OpenTKDemo
{public partial class FormGLControl : Form{private int vao, vbo, shaderProgram;private Matrix4 model, view, projection;private float rotationX = 0.0f, rotationY = 0.0f; // 旋转角度private bool isDragging = false;private Point lastMousePosition;public FormGLControl(){InitializeComponent();}private void glControl1_Load(object sender, EventArgs e){// 设置清屏颜色GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f);// 初始化 VAO 和 VBOvao = GL.GenVertexArray();vbo = GL.GenBuffer();GL.BindVertexArray(vao);float[] vertices = {// 顶点位置       // 颜色0.0f,  0.5f,  0.0f,  1.0f, 0.0f, 0.0f, // 顶点1(x,y,z,red,green,blue)-0.5f, -0.5f,  0.5f,  0.0f, 1.0f, 0.0f, // 顶点20.5f, -0.5f,  0.5f,  0.0f, 0.0f, 1.0f, // 顶点30.0f, -0.5f, -0.5f,  1.0f, 1.0f, 0.0f  // 顶点4};int[] indices = {0, 1, 2, // 正面0, 2, 3, // 右面0, 3, 1, // 左面1, 3, 2  // 底面};int ebo = GL.GenBuffer();GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);GL.BindBuffer(BufferTarget.ElementArrayBuffer, ebo);GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(int), indices, BufferUsageHint.StaticDraw);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);// 创建并编译着色器string vertexShaderSource = @"#version 330 corelayout (location = 0) in vec3 aPosition;layout (location = 1) in vec3 aColor;out vec3 vertexColor;uniform mat4 model;uniform mat4 view;uniform mat4 projection;void main(){gl_Position = projection * view * model * vec4(aPosition, 1.0);vertexColor = aColor;}";string fragmentShaderSource = @"#version 330 corein vec3 vertexColor;out vec4 FragColor;void main(){FragColor = vec4(vertexColor, 1.0);}";int vertexShader = CompileShader(ShaderType.VertexShader, vertexShaderSource);int fragmentShader = CompileShader(ShaderType.FragmentShader, fragmentShaderSource);shaderProgram = GL.CreateProgram();GL.AttachShader(shaderProgram, vertexShader);GL.AttachShader(shaderProgram, fragmentShader);GL.LinkProgram(shaderProgram);// 删除着色器GL.DeleteShader(vertexShader);GL.DeleteShader(fragmentShader);// 初始化矩阵view = Matrix4.LookAt(new Vector3(0.0f, 0.0f, 2.0f), Vector3.Zero, Vector3.UnitY);projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45.0f), glControl1.Width / (float)glControl1.Height, 0.1f, 100.0f);GL.BindVertexArray(0);}private void glControl1_Paint(object sender, PaintEventArgs e){// 清屏GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);// 绘制三角锥GL.UseProgram(shaderProgram);model = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(rotationX)) *Matrix4.CreateRotationY(MathHelper.DegreesToRadians(rotationY));GL.UniformMatrix4(GL.GetUniformLocation(shaderProgram, "model"), false, ref model);GL.UniformMatrix4(GL.GetUniformLocation(shaderProgram, "view"), false, ref view);GL.UniformMatrix4(GL.GetUniformLocation(shaderProgram, "projection"), false, ref projection);GL.BindVertexArray(vao);GL.DrawElements(PrimitiveType.Triangles, 12, DrawElementsType.UnsignedInt, 0);glControl1.SwapBuffers();}private void glControl1_Resize(object sender, EventArgs e){GL.Viewport(0, 0, glControl1.Width, glControl1.Height);projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45.0f), glControl1.Width / (float)glControl1.Height, 0.1f, 100.0f);}private void glControl1_MouseDown(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left){isDragging = true;lastMousePosition = e.Location;}}private void glControl1_MouseUp(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left){isDragging = false;}}private void glControl1_MouseMove(object sender, MouseEventArgs e){if (isDragging){int deltaX = e.X - lastMousePosition.X;int deltaY = e.Y - lastMousePosition.Y;rotationX += deltaY * 0.5f;rotationY += deltaX * 0.5f;lastMousePosition = e.Location;glControl1.Invalidate();}}private 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 status);if (status == 0){GL.GetShaderInfoLog(shader, out string infoLog);throw new Exception($"Error compiling shader ({type}): {infoLog}");}return shader;}}
}

 运行如图:

可以拖动旋转:

http://www.lryc.cn/news/519886.html

相关文章:

  • 排序的本质、数据类型及算法选择
  • Python的列表基础知识点(超详细流程)
  • HarmonyOS鸿蒙开发 弹窗及加载中指示器HUD功能实现
  • 【Ubuntu与Linux操作系统:一、Ubuntu安装与基本使用】
  • React 元素渲染
  • 【2024年华为OD机试】 (C卷,100分)- 括号匹配(Java JS PythonC/C++)
  • 解锁企业数字化转型新力量:OpenCoze(开源扣子)
  • 【网络云SRE运维开发】2025第2周-每日【2025/01/12】小测-【第12章 rip路由协议】理论和实操考试题解析
  • 【微服务】8、分布式事务 ( XA 和 AT )
  • CVE-2025-22777 (CVSS 9.8):WordPress | GiveWP 插件的严重漏洞
  • TypeScript Jest 单元测试 搭建
  • 基于 SSH 的任务调度系统
  • filestream安装使用全套+filebeat的模块用法
  • java项目之房屋租赁系统源码(springboot+mysql+vue)
  • sap mm学习笔记
  • 代码随想录_链表
  • EF Code 并发控制
  • ceph fs status 输出详解
  • FFmpeg Muxer HLS
  • 如何用SQL语句来查询表或索引的行存/列存存储方式|OceanBase 用户问题集锦
  • 回归预测 | MATLAB实GRU多输入单输出回归预测
  • 【OpenGL/Assimp】渲染模型、半透明材质与封装光源
  • pandas与sql对应关系【帮助sql使用者快速上手pandas】
  • Linux WEB漏洞
  • 音视频入门基础:RTP专题(2)——使用FFmpeg命令生成RTP流
  • 大语言模型预训练、微调、RLHF
  • vue3后台系统动态路由实现
  • 解决idea中无法拖动tab标签页的问题
  • WMS仓库管理系统,Vue前端开发,Java后端技术源码(源码学习)
  • 25/1/12 嵌入式笔记 学习esp32