原文地址:https://billc.io/2019/10/fpainter/

计算机图形学的第一个大作业是用 OpenGL 或 DirectX3d 实现一个平面的画图,应当具备直线和圆形的功能。正好国庆放假时间比较充裕,就稍微完善了一下界面,实现了一个画图。

随手画的一个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) 实现的一个简易画图版的更多相关文章

  1. [OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题

    [OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题 本文参考了(http://www.zeuscmd.com/tutorials/open ...

  2. 【OpenGL(SharpGL)】支持任意相机可平移缩放的轨迹球实现

    [OpenGL(SharpGL)]支持任意相机可平移缩放的轨迹球 (本文PDF版在这里.) 在3D程序中,轨迹球(ArcBall)可以让你只用鼠标来控制模型(旋转),便于观察.在这里(http://w ...

  3. OpenGL学习——搭建OpenGL运行环境——生成一个空白视口——基于GLFW&GLEW

    最近学习OpenGL,读OpenGL宝典一头蒙,各种gl函数不知所云.逐决定先搭OpenGL运行环境,详细如下. 1.首先OpenGL是什么?是一个标准规范,是一个巨大的状态机,并无具体实现,大多数实 ...

  4. 基于OpenGL编写一个简易的2D渲染框架-06 编写一个粒子系统

    在这篇文章中,我将详细说明如何编写一个简易的粒子系统. 粒子系统可以模拟许多效果,下图便是这次的粒子系统的显示效果.为了方便演示,就弄成了一个动图. 图中,同时显示了 7 种不同粒子效果,看上去效果挺 ...

  5. .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”

    FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...

  6. 自己来实现一个简易的OCR

    来做个简易的字符识别 ,既然是简易的 那么我们就不能用任何的第三方库 .啥谷歌的 tesseract-ocr, opencv 之类的 那些玩意是叼 至少图像处理 机器视觉这类课题对我这种高中没毕业的人 ...

  7. 基于 getter 和 setter 撸一个简易的MVVM

    Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ...

  8. 探秘Tomcat——一个简易的Servlet容器

    即便再简陋的服务器也是服务器,今天就来循着书本的第二章来看看如何实现一个servlet容器. 背景知识 既然说到servlet容器这个名词,我们首先要了解它到底是什么. servlet 相比你或多或少 ...

  9. 使用Windows Form 制作一个简易资源管理器

    自制一个简易资源管理器----TreeView控件 第一步.新建project,进行基本设置:(Set as StartUp Project:View/Toolbox/TreeView) 第二步.开始 ...

随机推荐

  1. 在HADOOP中使用MRUNIT进行单元测试

    在HADOOP中使用MRUNIT进行单元测试 前提 1. 了解JUnit4.x的使用. 2. 了解Mock的概念在单元测试中的应用. 3. 了解Hadoop中MapReduce的编程模型. 如果您对J ...

  2. HDU1233 还是畅通工程

    题目: Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连 ...

  3. 吴裕雄--天生自然python学习笔记:Python CGI编程

    什么是CGI CGI 目前由NCSA维护,NCSA定义CGI如下: CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上如:HTTP服务器,提供同客户 ...

  4. 吴裕雄--天生自然 R语言开发学习:中级绘图(续二)

    #------------------------------------------------------------------------------------# # R in Action ...

  5. SSM框架三分钟搞定分页查询

    使用的国产第三方jar   pagehelper 里面的基本属性值 //当前页 private int pageNum; //每页的数量 private int pageSize; //当前页的数量 ...

  6. MicrosoftOfficeProfessionalPlus2013傻瓜式激活工具

    用微软的office系列,总是提示需要输入秘钥,直接找个破解软件破解算了. 破解软件地址:http://www.3322.cc/soft/10037.html 1.下载解压: 2.点击office系列 ...

  7. for循环的应用

    for循环的应用:迭代法,穷举法. 一.迭代法:(有一定规律) 每次循环都是从上次运算结果中获得数据,本次运算的结果都是要为下次运算做准备. 例:1.100以内所有数的和. int sum = 0;f ...

  8. mysqldump: Got error: 1449: The user specified as a definer ('user'@'%') does not exist when using LOCK TABLES

    报错:一个库用mysqldump -u -p --opt --force -e --max_allowed_packet= --net_buffer_length= --databases备份时报错如 ...

  9. Java工厂模式解耦 —— 理解Spring IOC

    Java工厂模式解耦 -- 理解Spring IOC 最近看到一个很好的思想来理解Spring IOC,故记录下来. 资源获取方式 主动式:(要什么资源都自己创建) 被动式:(资源的获取不是我们创建, ...

  10. LeetCode--链表3-经典问题

    LeetCode--链表3-经典问题 题1 反转链表 第一次代码超出时间限制 原因是,反转之后链表的尾部节点和头结点连上了 /** * Definition for singly-linked lis ...