您现在的位置是:首页 >技术杂谈 >.Net平台下OpenGL绘制图形(1)(VS2019,Winform,C#)网站首页技术杂谈
.Net平台下OpenGL绘制图形(1)(VS2019,Winform,C#)
1、介绍
OpenGL(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。这个接口由近350个不同的函数调用组成,用来绘制从简单的图形到比较复杂的三维景象。而另一种程序接口系统是仅用于Microsoft Windows上的Direct3D。OpenGL常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。
OpenGL的高效实现(利用了图形加速硬件)存在于Windows,部分UNIX平台和Mac OS。这些实现一般由显示设备厂商提供,而且非常依赖于该厂商提供的硬件。开放源代码库Mesa是一个纯基于软件的图形API,它的代码兼容于OpenGL。但是,由于许可证的原因,它只声称是一个“非常相似”的API。
当今,OpenGL是视频行业领域中用于处理2D/3D图形的最为广泛接纳的API,在此基础上,为了用于计算机视觉技术的研究,从而催生了各种计算机平台上的应用功能以及设备上的许多应用程序。其是独立于视窗操作系统以及操作系统平台,可以进行多种不同领域的开发和内容创作,简而言之,其帮助研发人员能够实现PC、工作站、超级计算机以及各种工控机等硬件设备上实现高性能、对于视觉要求极高的高视觉图形处理软件的开发。
2、工具
在C#中直接调用OpenGL函数比较繁琐,一般不直接使用。我们可以借助第三方开源库,比如SharpGL、CsGL、OpenTK、Tao框架等。下面对这些框架逐一介绍,其中Tao已经停止维护和更新了,可以被OpenTK替代,这里就不介绍了。
3、winform窗体绘制立方体
VS2019,.NetFramework4.7
1,创建空解决方案项目OpenGLProjectApp
2、删除产生的项目,解决方案右键添加项目,选择windows窗体应用,项目名称为SharpGLFormsApp1
3、项目添加sharpgl引用
可以看到项目引用dll成功,同时工具箱多了一个类别
4,拖入不同控制,页面布局如图:
5、编写各个控件的事件,重点是那个openglcontrol的GDIDraw事件,完整代码:
using SharpGL;
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 SharpGLFormsApp1
{
public partial class Form1 : Form
{
/// <summary>
/// 默认绘画模式为线条
/// </summary>
private uint _model = OpenGL.GL_LINE_LOOP;
/// <summary>
/// X轴坐标
/// </summary>
private float _x = 0;
/// <summary>
/// Y轴坐标
/// </summary>
private float _y = 0;
/// <summary>
/// Z轴坐标
/// </summary>
private float _z = 0;
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 复位事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
_x = _y = _z = 0;
tbX.Value = tbY.Value = tbZ.Value = Convert.ToInt32(_x);
label1.Text = "X轴" ;
label2.Text = "Y轴";
label3.Text = "Z轴";
}
/// <summary>
/// 线条选择事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rbline_CheckedChanged(object sender, EventArgs e)
{
_model = OpenGL.GL_LINE_LOOP;
}
/// <summary>
/// 球面事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rbfull_CheckedChanged(object sender, EventArgs e)
{
_model = OpenGL.GL_QUADS;
}
/// <summary>
/// 控件绘图事件
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void openGLControl1_GDIDraw(object sender, RenderEventArgs args)
{
// 创建一个GL对象
SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); // 清空屏幕
gl.LoadIdentity(); // 重置
gl.Translate(0.0f, 0.0f, -6.0f); // 设置坐标,距离屏幕距离为6
gl.Rotate(_x, 1.0f, 0.0f, 0.0f); // 绕X轴旋转
gl.Rotate(_y, 0.0f, 1.0f, 0.0f); // 绕Y轴旋转
gl.Rotate(_z, 0.0f, 0.0f, 1.0f); // 绕Z轴旋转
gl.Begin(_model); // 绘制立方体
gl.Color(0.0f, 1.0f, 0.0f); // 设置颜色
//绘制其中一个面
gl.Vertex(1.0f, 1.0f, -1.0f);
gl.Vertex(-1.0f, 1.0f, -1.0f);
gl.Vertex(-1.0f, 1.0f, 1.0f);
gl.Vertex(1.0f, 1.0f, 1.0f);
//如下类同
gl.Color(1.0f, 0.5f, 0.0f);
gl.Vertex(1.0f, -1.0f, 1.0f);
gl.Vertex(-1.0f, -1.0f, 1.0f);
gl.Vertex(-1.0f, -1.0f, -1.0f);
gl.Vertex(1.0f, -1.0f, -1.0f);
gl.Color(1.0f, 0.0f, 0.0f);
gl.Vertex(1.0f, 1.0f, 1.0f);
gl.Vertex(-1.0f, 1.0f, 1.0f);
gl.Vertex(-1.0f, -1.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 1.0f);
gl.Color(1.0f, 1.0f, 0.0f);
gl.Vertex(1.0f, -1.0f, -1.0f);
gl.Vertex(-1.0f, -1.0f, -1.0f);
gl.Vertex(-1.0f, 1.0f, -1.0f);
gl.Vertex(1.0f, 1.0f, -1.0f);
gl.Color(0.0f, 0.0f, 1.0f);
gl.Vertex(-1.0f, 1.0f, 1.0f);
gl.Vertex(-1.0f, 1.0f, -1.0f);
gl.Vertex(-1.0f, -1.0f, -1.0f);
gl.Vertex(-1.0f, -1.0f, 1.0f);
gl.Color(1.0f, 0.0f, 1.0f);
gl.Vertex(1.0f, 1.0f, -1.0f);
gl.Vertex(1.0f, 1.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, -1.0f);
gl.End(); // 结束绘制
}
/// <summary>
/// X轴拖动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tbX_Scroll(object sender, EventArgs e)
{
int x = tbX.Value;
_x = x;
label1.Text = "X:" + x;
}
/// <summary>
/// Y轴拖动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tbY_Scroll(object sender, EventArgs e)
{
int y = tbY.Value;
_y = y;
label2.Text = "Y:" + y;
}
/// <summary>
///Z轴拖动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tbZ_Scroll(object sender, EventArgs e)
{
int z = tbZ.Value;
_z = z;
label3.Text = "Z:" + z;
}
}
}
6、运行效果