使用 C# 和 OpenGL (SharpGL) 实现的一个简易画图版
原文地址:https://billc.io/2019/10/fpainter/
计算机图形学的第一个大作业是用 OpenGL 或 DirectX3d 实现一个平面的画图,应当具备直线和圆形的功能。正好国庆放假时间比较充裕,就稍微完善了一下界面,实现了一个画图。
 随手画的一个Logo
随手画的一个Logo关于 SharpGL
为了使 OpenGL 能正确地与 C# 互动,可以采用动态链接的方式直接手动将 OpenGl 的 dll 链接进自己工程中,但这种方法比较繁琐,况且网上已经有许多人做了重复的工作,于是我选择了一个似乎并不是特别受欢迎的包装库 SharpGL 来在 C# 中使用 OpenGL 的函数。
如果采用 OpenGLControl 控件获取 OpenGL 对象,那么使用 SharpGL 的代码风格会是这样:
//C#
SharpeGL.OpenGL gl = glCanvas.OpenGL;
gl.Color(0, 0, 0);
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
gl.Translate(-4.68f, 4.11f, -10f);
相比对应的 OpenGL 在 C/C++ 中的代码,可以流畅地转换。同时这个库还省去了 Glut 函数后面的 3f 等恼人的参数,全部重载了一起。
//C
glColor3f(0, 0, 0);
glClear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-4.68f, 4.11f, -10f);
你可以在这里 https://github.com/dwmkerr/sharpgl 了解到关于 SharpGL 的更多信息。
运行效果

主要的功能如图。基本的画图功能都可以实现,刷新率大概在每秒30帧的样子。需要运行在 .Net Framework 4.6以上,因为需要一个高 dpi 感知的 manifest。
目前还有两个需要探索的问题,一个是在拖动绘制直线的时候能够实时显示当前的绘制效果而不是抬起鼠标之后才绘制。也许要设计一些 buffer 相关的知识但目前自己的能力似乎还做不到。
同时使用如下代码开启抗锯齿后,圆形的绘制会有较大问题。在每一次绘制的时候多边形都会填充一次,造成绘制出来的圆形会成为这个样子:
 奇怪的抗锯齿
奇怪的抗锯齿//抗锯齿
gl.Enable(OpenGL.GL_BLEND);
gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);
gl.Enable(OpenGL.GL_POINT_SMOOTH);
gl.Enable(OpenGL.GL_LINE_SMOOTH);
gl.Enable(OpenGL.GL_POLYGON_SMOOTH);
//圆形的绘制代码
case Tools.circle:
//使用参数函数 x = Acos; y = Bsin画椭圆
double lenA = Math.Abs(fx - pointQueue.Peek().fx) / 2.0;
double lenB = Math.Abs(fy - pointQueue.Peek().fy) / 2.0;
fPoint center = new fPoint((fx + pointQueue.Peek().fx) / 2.0, (fy + pointQueue.Peek().fy) / 2.0);
int n = 90; //精度,以n边的多边形代替椭圆
gl.Begin(OpenGL.GL_POLYGON);
{
for (double alpha = 0; alpha < Math.PI * 2; alpha += Math.PI / n)
{
gl.Vertex(center.fx + Math.Cos(alpha) * lenA, center.fy + Math.Sin(alpha) * lenB, 0f);
}
}
gl.End();
pointQueue.Clear();
break;
Code
你可以在这里找到源代码: https://github.com/BillChen2000/LearningRepo/tree/master/Course/ComputerGraphics/FPainter
之前本来的要求是用 MFC 实现图形界面,但看了看上世纪的框架文档实在是没有心思继续钻研下去。不知道什么时候大学的老师们能够在 ppt 里稍微去掉一些 199x 年的古董。
使用 C# 和 OpenGL (SharpGL) 实现的一个简易画图版的更多相关文章
- [OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题
		[OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题 本文参考了(http://www.zeuscmd.com/tutorials/open ... 
- 【OpenGL(SharpGL)】支持任意相机可平移缩放的轨迹球实现
		[OpenGL(SharpGL)]支持任意相机可平移缩放的轨迹球 (本文PDF版在这里.) 在3D程序中,轨迹球(ArcBall)可以让你只用鼠标来控制模型(旋转),便于观察.在这里(http://w ... 
- OpenGL学习——搭建OpenGL运行环境——生成一个空白视口——基于GLFW&GLEW
		最近学习OpenGL,读OpenGL宝典一头蒙,各种gl函数不知所云.逐决定先搭OpenGL运行环境,详细如下. 1.首先OpenGL是什么?是一个标准规范,是一个巨大的状态机,并无具体实现,大多数实 ... 
- 基于OpenGL编写一个简易的2D渲染框架-06 编写一个粒子系统
		在这篇文章中,我将详细说明如何编写一个简易的粒子系统. 粒子系统可以模拟许多效果,下图便是这次的粒子系统的显示效果.为了方便演示,就弄成了一个动图. 图中,同时显示了 7 种不同粒子效果,看上去效果挺 ... 
- .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”
		FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ... 
- 自己来实现一个简易的OCR
		来做个简易的字符识别 ,既然是简易的 那么我们就不能用任何的第三方库 .啥谷歌的 tesseract-ocr, opencv 之类的 那些玩意是叼 至少图像处理 机器视觉这类课题对我这种高中没毕业的人 ... 
- 基于 getter 和 setter 撸一个简易的MVVM
		Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ... 
- 探秘Tomcat——一个简易的Servlet容器
		即便再简陋的服务器也是服务器,今天就来循着书本的第二章来看看如何实现一个servlet容器. 背景知识 既然说到servlet容器这个名词,我们首先要了解它到底是什么. servlet 相比你或多或少 ... 
- 使用Windows Form 制作一个简易资源管理器
		自制一个简易资源管理器----TreeView控件 第一步.新建project,进行基本设置:(Set as StartUp Project:View/Toolbox/TreeView) 第二步.开始 ... 
随机推荐
- Adam项目展示微软研究院人工智能领域新突破
			编者按:在美国时间7月14日举行的2014年微软教育峰会上,Adam项目面对牵上台的3只小狗,一一准确地报出了它们的品种.Adam项目代表了微软研究院在机器学习和人工智能领域的前沿进展.它可不仅仅认得 ... 
- 从Surface 3发布 看微软快速转向的根由
			3发布 看微软快速转向的根由" title="从Surface 3发布 看微软快速转向的根由"> 平地一声惊雷起,微软突然送惊喜!在毫无征兆的情况下,微软突然发布一 ... 
- github新建Repositories后具体操作步骤
			添加用户信息 第一个要配置的是你个人的用户名称和电子邮件地址.这两条配置很重要,每次 Git 提交时都会引用这两条信息,说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录: 1 2 git c ... 
- 手术Robot能取代医生吗?
			现在,机械自动化已经成为各领域为之神往的大趋势,从工业组装,到智能物流,再到餐饮.银行服务,以及娱乐等等,管理者无不处心积虑地降低成本.提高效率,其中,一个非常重要的手段就是利用机器取代人工.医院,作 ... 
- 状态模式(State)-设计模式
			软件模式是将模式的一般概念应用于软件开发领域,即软件开发的 总体指导思路或参照样板.软件模式并非仅限于设计模式,还包括 架构模式.分析模式和过程模式等,实际上,在软件生存期的每一个阶段都存在着一些被认 ... 
- 如何正确的hook方法objc_msgSend · jmpews
			如何正确的hook方法objc_msgSend 前言 如果希望对 Objective-C 的方法调用进行 log, 一个很好的解决方法就是 hook 方法 objc_msgSend, 当然想到的就是利 ... 
- Js对于数组去重提高效率一些心得
			最近在找工作,好几次面试都问过数组去重的问题.虽然问的都不一样,但是核心思想是没有变的. 第一种是比较常规的方法 思路: 构建一个新的数组存放结果 for循环中每次从原数组中取出一个元素,用这个元素循 ... 
- 从高知社区知乎变故事会,看论坛IP的夹缝生存
			   "海贼-王路飞"疯狂饰演多个角色答题的事件,最终以其被封杀为结果:知乎官方账号发表<知乎小管家工作笔记:我们封禁了几个伪造身份的帐号>,内容为公布了新一批 ... 
- node--CommonJS
			1.CommonJS 1)弥补js没有标准的缺陷 2.Node模块 1)分为核心模块和用户自定义模块 2)我们可以把公共的功能抽离为一个单独的js文件作为一个模块 其中的成员和属性外界无法访问,若要设 ... 
- python版md-to-html编辑器
			用PyQt5封装python-markdown,支持自定义样式. 详情:https://blog.phyer.cn/article/4523 
