基于MFC的OpenGL简易绘图系统
2022-05-30尤王杰
关键词:MFC;OpenGL;绘图系统;C++面向对象
中图法分类号:TP391 文献标识码:A
1概述
MFC 是微软公司开发的一个类库,以C++类的形式封装了Windows 的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中,MFC包含大量Windows 句柄封装类和很多Windows 的内建控件和组件的封装类[1] 。
OpenGL 是一个开放式图形库,是用于渲染2D 和3D 矢量图形的跨语言、跨平台的应用程序编程接口,是一个功能强大、支持底层绘制和造型能力的软件图形函数库。它独立于硬件和窗口系统,为程序员进行图形学相关的程序编写提供了极大的帮助[2] 。
绘图软件一般指基于计算机绘制图形的软件,如Windows 自带的画图软件等。它的开发语言和技术已经十分成熟。本系统实现了基于基本类库MFC 和OpenGL 图形库面向对象的二维图形绘制应用程序,可以实现绘图的功能同时也可以让软件开发人员对软件开发过程有进一步了解。
2软件开发环境
软件主要使用C++编程语言编写,使用了C++的基本库类MFC 和图形库OpenGL 以及C++常用库;开发软件的操作系统环境为Windows 10;软件的集成开发环境为Viusal Studio 2017;软件开发的硬件环境为16GB 內存,intel Core i5?9400F CPU(2.9GHz);软件支持跨平台使用,可以在不同操作系统中实现功能,同时可以进行本地保存[3] 。
3系统框架设计
本系统采用了C++编程语言以及面向对象的编程风格,其基本思想是将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。通过面向对象的方法,更利于用人理解的方式对复杂系统进行分析、设计与编程。同时,面向对象能有效提高编程的效率,通过封装技术,可以更高效地开发出一个全新的系统[4] 。本系统主要包含以下文件。
Drawing_system.h:应用程序的主头文件。其中,包括其他项目特定的标头(包括Resource.h),并声明Drawing_system 应用程序类。
Drawing_system.cpp:包含应用程序类CDrawing_system 的主应用程序源文件。
MainFrm.h,MainFrm.cpp: 包含框架类CMainFrame,该类派生自CMDIFrameWnd 并控制所有MDI框架功能。
ChildFrm. h,ChildFrm. cpp: 定义并实现CChildFrame 类,该类支持MDI 应用程序中的子窗口。
Drawing_systemDoc.h、Drawing_systemDoc.cpp:包含CGraphics_WorkDoc 类。编辑这些文件以添加特殊文档数据,并实现文件保存和加载(通过CGraphics_WorkDoc::Serialize)。
Drawing_SystemView.h、Drawing_systemView.cpp:包含CGraphics_WorkView 类。CGraphics_WorkView对象用于查看CGraphics_WorkDoc 对象。
LogDialog 类:实现了对话框的各种主要参数的设置,同时加入了消息处理机制,与其他模块相互连接。
通过在以上文件中进行基础类、全局变量、临时对象的申明,再结合OpenGL 库的函数调用,通过计算机图形学的思想实现图片的绘制:先由基础的点、线、多边形,加上色彩的渲染,将这些基本图元最终组合成一个完整的图形。同时,提供撤销、恢复、清空等功能,让用户拥有更好的使用体验,让程序更加健壮。此外,在图形绘制完成后,可以将绘制的图形存储成规定的模式,关闭软件后在下一次打开时再进行进一步编辑[5~8] 。
4软件的功能设计与实现
本系统的功能主要分为以下几个模块,即简单图元绘制、自由曲线绘制、橡皮擦、颜色选择、清空、撤销与恢复。
(1)简单图元绘制
在简单图元绘制模块中运用OpenGL 库相关的函数以及消息处理机制,实现一部分内置基本图元的绘制,如直线、三角形、矩形、圆形等。如图1 所示,这些图原是系统内部自带的图形。每一种图元可以使用一个容器进行保存。OpenGL 绘制简单图形结构如下。
glBegin(GL_LINES);∥绘制直线
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glEnd();
glBegin(GL_POLYGON);
glVertex3f(20.0, 10.0, 0.0);∥绘制多边形
glVertex3f(60.0, 30.0, 0.0);
glVertex3f(70.0, 45.0, 0.0);
glVertex3f(40.0, 75.0, 0.0);
glVertex3f(10.0, 60.0, 0.0);
glEnd();
(2)自由曲线绘制
在自由曲线绘制模块中使用C++标准库中提供的vector 容器,将绘制的曲线分段用vector 保存,通过记录鼠标当前在窗口上的位置返回坐标信息,最后通过OpenGL 库中曲线绘制的函数绘制出一条自由曲线。曲线实际上就是无数点的连接,设置一个很小的计时器返回实时鼠标位置坐标,在这些坐标上画点,就可以实现自由曲线的绘制。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_
BUFFER_BIT);
∥ 绘制场景
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
DrawPicture();
glPopMatrix();
∥ 交换缓冲区
SwapBuffers(wglGetCurrentDC());
int R=255, G=255, B=255;
vector FreeLine;
void Display() {
glColor3d(R ? 1.0 / 255, G ? 1.0 / 255, B ?
1.0 / 255);
glLineWidth(1);
glBegin(GL_LINE_STRIP);
for (int i=0; i < (int)FreeLine.size(); i++) {
glVertex2d(FreeLine[i].x, FreeLine[i].y);}
glEnd();
glFlush();
(3)橡皮擦
橡皮擦模块可以用于删除之前已经绘制的图形元素。橡皮擦的实现其实是自由曲线绘制的反向操作,由于之前绘制的图形都已经分别保存在各自的容器中,通过选取橡皮擦工具,在要擦除的地方移动鼠标,计算当前鼠标移动的曲线与之前已经存在的图形是否存在交集,如果存在交集,就在对应的图形容器中删去该元素即可。其基本代码如下。
vector EraserLine;
void Display() {
glLineWidth(6);
glBegin(GL_LINE_STRIP);
glColor3d(0, 0, 0);
for (int i=0; i < (int)EraserLine.size(); i++) {
glVertex2d(EraserLine[i].x, EraserLine[i].y);}
glEnd();
glFlush();
if (Case) {
return;}
mark_eraser.push_back(0);
mark_id[Stack_top] = (int) mark_eraser.size( )- 1;
Case=0; Draw_Operator[Stack_top++] =6;
InvalidateRect(NULL, FALSE);
(4)颜色选择
颜色选择模块为用户提供了一些系统自带的常见颜色种类,如黑、白、红、黄、蓝、绿等。同时,也提供了用户自由配置颜色的选项,即用户可以自由选择R,G,B 颜色分量的值,预览生成的颜色效果来选择自己喜欢的颜色进行绘制。其基本代码如下。
MessageBox(_T(" 请选择直线与点的颜色"),
_T("提示"));
COLORREF color=RGB(255, 0, 0);
CColorDialog colorDlg(color);
if (IDOK= =colorDlg.DoModal()) {∥ 获取颜色
对话框中选择的颜色值
color=colorDlg.GetColor();∥ 获取R、G、B 分量
m_color.R=GetRValue(color);
m_color.G=GetGValue(color);
m_color.B=GetBValue(color);
(5)清空
清空模块为用户提供了直接清空画板的功能,以实现初始化的功能。其实清空操作十分方便,由于之前所有画过的图形都被保存在了各自的容器中,所以要清空画板,将各个容器中的元素全部清空即可,可以使用vector 的clear 函数来实现。由于清空功能有一定的危险性,所以还需要考虑将其撤销。
(6)撤销与恢复
撤销是用于取消上一步的操作,我们可以通过将每一步操作都放在一个栈中,当使用撤销功能时,弹出栈顶操作,并将其反向执行来实现撤销的功能。而恢复就是在撤销的基础上再取消,我们同样可以使用一个栈来保存已经撤销的步骤,当执行操作时,弹出栈顶再次执行即可。有了撤销和恢复功能,我们就可以避免一些误操作带来的不良后果,让软件更加健壮。
5结论
基于MFC 和OpenGL,運用了面向对象编程思想开发的简易绘图系统,为用户提供了简单易操作的绘图工具。运用计算机进行图像的绘制,减小了时间以及空间的影响,使图形更加精确,更加有利于对图形数据的可视化分析。采用基于MFC 与OpenGL 以及现代化的软件开发框架,降低了软件对硬件和平台的要求,能节省计算量和内存,对比传统的绘图系统,本系统具有程序体积小、运行速度快、对硬件要求低、具有较好的适应性等优点。同时,软件的整体设计过程也能对软件开发初学者提供一些帮助。
作者简介:
尤王杰(2000—),本科,研究方向:计算机图形学。