原文地址: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. css - 原生变量及使用函数 var()

    零.序言 前两天在逛 blog 的时候看见一些内联样式新奇的写法时很纳闷,虽然说不上多么熟练,但是从来没见过  --color: brown 这样的写法,百度一番之后仍然没啥头绪,今天偶然看到一篇文章 ...

  2. Servlet.service() for servlet [appServlet] in context with path [/item] threw exception [Request processing failed

    以前犯过的一个小错误,不过忘记怎么修改了,所以还是记录下来好一点 严重: Servlet.service() for servlet [appServlet] in context with path ...

  3. Luogu_2061_[USACO07OPEN]城市的地平线City Horizon

    题目描述 Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the cit ...

  4. HexoC++第04课 构造析构.md

    C++第04课 构造析构.mdhtml {overflow-x: initial !important;}#write, body { height: auto; } #write, #write h ...

  5. SWUST OJ 有趣的三位数(0319)

    有趣的三位数(0319) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 158 Accepted: 62   Description ...

  6. 一站式自动化测试平台 http://www.Autotestplat.com

    Autotestplat 一站式自动化测试平台及解决方案 自动化平台开发 3.1 自动化平台开发方案 3.1.1 功能需求 支持 API.AppUI.WebUI 性能等自动化测试,集成实现测试用例管理 ...

  7. 网络编程OSI介绍

    网络编程 软件开发架构 c/s架构(client/server) c:客户端 s:服务端 客户端和服务器端架构,这种架构是从用户层划分的,一般客户端就是在用户电脑上安装的应用程序,而服务端就是公司里的 ...

  8. 通过zxing生成二维码

    二维码现在随处可见,在日常的开发中,也会经常涉及到二维码的生成,特别是开发一些活动或者推广方面的功能时,二维码甚至成为必备功能点.本文介绍通过 google 的 zxing 包生成带 logo 的二维 ...

  9. ActiveMQ学习总结(一)

    自己写的网上商城项目中使用了ActiveMQ,虽然相比于RabbitMQ,kafka,RocketMQ等相比,ActiveMQ可能性能方面不是最好的选择,不过消息队列其实原理区别不大,这里对学过的关于 ...

  10. TensorFlow学习笔记(一)

    [TensorFlow API](https://www.tensorflow.org/versions/r0.12/how_tos/variable_scope/index.html) Tensor ...