基于OpenGL的实验室用滑动变阻器的设计与实现

(整期优先)网络出版时间:2019-12-05
/ 3
摘 要 本文介绍了基于OpenGL的实验室用滑动变阻器的设计与实现技术,并介绍模板缓存在图形设计中的应用、滑动变阻器的三维可视化以及通过鼠标实现其缩放和移动等技术实现功能。

关键字 OpenGL;滑动变阻器;仿真;纹理;模板缓存


1 引言

理学是一门实验科学,学生不仅可以从物理实验中获取感性认识,加强探索能力和培养动手技巧,而且物理实验在增加物理教学的趣味性方面也有着举足轻重的作用。随着现代科学技术及计算机技术的飞速发展,计算机在辅助物理实验教学中,如模拟实验过程、演示实验原理、进行数据处理、实验控制和测量等方面都有了广泛的应用,这也有力地促进了实验教学的改革步伐。在计算机辅助物理实验教学中,CAI课件在辅助实验教学中起着举足轻重的作用。物理实验CAI课件模拟实验过程、演示实验原理、进行实验控制等的仿真程度越高,对实验教学的效果影响就越好。目前,教师多以Flash等工具来制作多媒体实验教学课件,很多情况下不能模拟实验过程,更加难实现进行实验控制,如实现直流电路中的滑动变阻器根据滑块的移动来及时准确地控制电路,实现直流电路的仿真控制。本文将要介绍在OpenGL环境下,实验室用滑动变阻器的设计思路和实现方法。

2 OpenGL简介

OpenGL是一个工业标准的三维计算机图形软件接口,是美国高级图形和高性能计算机系统公司(SGL)开发的三维图形库。它实际上是与图形硬件完全无关的程序设计API,独立于操作系统,有着强大的图形功能和良好的跨平台移植能力,具有可靠性、可扩展性强、伸缩性好、灵活性强、易用等特点。OpenGL实现二维和三维的高级图形技术,在性能上表现得异常优越,它包括建模、变换、颜色模式设置、光照与材质设置、双缓存动画以及更先进的能力,如纹理映射、物体运动模糊等。OpenGL的这些能力为实现逼真的三维渲染效果,建立交互的三维景观等提供了优秀的软件工具。

3 实验室用滑动变阻器的设计与实现

3.1 需求分析

实验室用滑动变阻器是直流电路中最常用的实验仪器之一。系统应提供多种交互手段,用户和系统的交互主要通过鼠标和键盘进行。键盘主要应用在辅助鼠标进行多个物体的选择,其他的交互都是用鼠标来完成。系统设计中的滑动变阻器能够根据所连接在电路中的接线柱和滑块的位置来及时准确地改变电路中的电阻,同时系统也必须提供将滑动变阻器连接到电路中的接口。

3.2 功能

⑴缩放和移动。主要实现滑动变阻器在上下左右和对角线方向的缩放功能,可以通过鼠标的拖动来完成(如图1)。

1128352297.jpg

图1 鼠标缩放图像

⑵滑块移动。滑动变阻器在电路中电阻的变化主要是通过滑动滑块来实现的。在正确连接的情况下,滑块移动能够改变滑动变阻器在电路中的有效电阻,从而实现变阻器在电路中的限流、分压作用等。本文中的滑块移动功能是通过在滑块上绑定一个点,这个点和滑块彼此关联来实现的,通过鼠标拖动点来实现滑块移动,效果如图2所示。

1128373547.jpg

图2 使用鼠标拖动滑块

⑶接线柱。滑动变阻器在电路中起到保护电路、限制电路电流和分担电压等作用,是通过使用接线柱将滑动变阻器连接到电路中来实现的,所以接线柱的连接功能是必不可少的(如图3)。

112837597.jpg


图3 接线柱功能

4 设计实现关键技术

4.1 纹理贴图技术

纹理贴图技术又称为纹理映射技术,它是计算机图形学中广泛应用的一项重要技术。本文选用纹理贴图技术是出于两方面的考虑,第一,使用OpenGL建模所创建的几何造型不能够描述物体的微观细节,而利用纹理图像可以达到模拟物体表面丰富的细节的目的,在很大程度上可以提高图形的真实性;第二,采用纹理映射的方法,可以很好地简化建模过程。本文中的滑动变阻器造型,如果使用OpenGL直接建模时有许多的细节需要表现,想要创建出真实感非常强的滑动变阻器,需要的工作量是很大的,若采用纹理映射,只要创建简单的模型。在这里使用OpenGL绘制两个简单的正方形模型,分别使用经过处理的三维立体效果很好的不含滑动变阻器滑块的图片和单独的滑块图片贴到模型表面即可。相比较而言,使用纹理贴图的工作量要小很多。

纹理映射(Texture Map)是将指定的图像数据应用到一个几何图元上,使用纹理绘制的一般步骤为:导入纹理,将纹理贴图到几何图形上。

4.1.1 导入纹理

应用纹理绘制的第一步就是要将纹理载入到内存中,同时设置纹理图像。下面的代码能实现该功能:

::glGenTextures(1,&m_textureNames);

BITMAP BM;

HBITMAP hBmp = (HBITMAP) ::LoadImage (NULL, m_bmpFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMF ILE|LR_ CREATEDIBSECTION);

::GetObject(hBmp, sizeof (BM), &BM);

::glBindTexture(GL_TEXTURE_2D, m_textureNames);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BM.bmWidth, BM.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED _BYTE, BM.bmBits);

其中m_textureNames表示的是需要载入的纹理图片的文件名参数,可以实现对24位位图文件的载入。

在将纹理应用到几个图形之前,还需要指定纹理时的过滤方式。

4.1.2 将纹理贴图到几何图形上

将纹理贴图到几何图形上的关键问题就是指定纹理坐标,纹理坐标控制纹理图像中的像素是按照什么样的方式映射到几何图形上。OpenGL中指定纹理坐标的函数是void glTexCoord{1234}{sifd}{v}(TYPE coords) ,贴图效果如图4所示。

1128386422.jpg


图4 纹理贴图效果

4.2 模板缓冲区的使用

从图4可以看到,纹理贴图以后,滑块上有一部分白色区域覆盖了下一层的贴图,使得两个图片不能够很好地融合在一起,通过使用OpenGL中的模板缓冲技术可以解决这样的问题,就是使用一个模板图案来渲染一个不规则的形状,将滑块上的白色区域去掉。

4.2.1 模板缓存

在现实世界中,模板就是一块平的纸板或其它材料,模板缓存的用途之一,就是将绘图范围限制在屏幕的特定区域。模板缓存用来进行复杂的掩模(masking)操作。一个复杂的形状可以存储在模板缓存里,然后绘制子序列操作可以使用模板缓存里的内容来决定是否更新象素。

4.2.2 使用模板缓存的操作方法

4.2.2.1 申请模板缓存区

为了使用OpenGL的模板功能,首先必须使用平台特定的OpenGL设置过程请求一个模板缓存区。在以VC++.NET为基础的OpenGL平台中,是在设置像素格式时在PIXELFORMATDESCRIPTOR结构中指定的模板缓存,并且需要指定模板缓存的位数。如果使用GLUT,在初始化显示模式时请求一个模板缓存区,下面的代码设置了带模板缓存的双缓存RGB颜色缓存区:

glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_STENCIL)。

4.2.2.2 模板测试

现代硬件加速的OpenGL现实中,模板操作相对较为快速,但是仍然可以并且有必要使用glEnable/glDisable来及时打开和关闭模板测试功能。

打开模板测试以后,绘图只在那些通过了模板测试的位置进行。在进行模板测试之前,指定要写入模板缓存区的清除值,通过函数glClearStencil来完成,函数原型为void glClearStencil(Glint s)。模板测试的设置可以通过下面的函数完成:

void glStencilFunc(Glenum func,Glint ref,Gluint mask)。func参数的值是告诉OpenGL如何把已经存储在模板缓存中的与ref参数所指定的值进行比较。也可以指定一个掩码,在进行比较之前,将指定的掩码与ref值和模板缓存区中的值进行AND操作。

4.2.2.3 创建模板图案

在绘图之前,要确保模板缓存区被清除,调用函数glClear()来清除缓存,函数原型为void glClear(Glbitfield mask),在清除操作中所使用的值是由前面的函数glClearStencil(Glint s)设置的。在启用了模板测试之后,就使用glStenceFunc函数的参数与存储在模板缓存区内的值进行测试。根据测试结果,值片段或者被写入,或者丢弃。模板缓存区本身在测试过程中也会进行修改,进入模板缓存区的值取决于如何调用glStencilOp函数:

void glStenclOp(Glenum fail,Glenum zfail,Glenum zpass)。函数中的参数值告诉OpenGL如果模板测试失败,应该如何修改模板缓存区的值。接下来要创建模板图案,本文中所创建的模板图案是滑块中的白色区域,使用自定义函数void DrawMoveRheostat()来实现。

4.2.2.4 实现代码

在本文中使用模板缓存来实现去除滑动变阻器滑块中的白色区域的实现代码如下所示:

glDrawBuffer(GL_NONE);

glEnable(GL_STENCIL_TEST);

glClearStencil(0x1);

glStencilFunc(GL_ALWAYS, 0x1, 0x1);

glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);

glClear(GL_STENCIL_BUFFER_BIT);

DrawPolygon();

glDrawBuffer(GL_BACK);

glStencilFunc(GL_EQUAL, 0x0, 0x1);

glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

Draw(m_textureNames);

glDisable(GL_STENCIL_TEST);

其中Draw(m_textureNames)函数是自定义,完成对纹理图片的绘制,m_textureNames表示的是需要载入的纹理图片的文件名参数。实现效果如图5所示。

4.2.2.5 实现代码中的函数DrawPolygon()

通过上面的分析可以知道,使用模板缓存是为了去除滑块中的白色区域,而自定义函数DrawPolygon()在程序中的功能是用来创建模板图案,也就是在函数中绘制滑块中白色区域以外的那部分区域,这部分是一个不规则的多边形。OpenGL中多边形的创建规则,一是所有的多边形都必须是平面的,二是多边性的边必须不相交,并且多边形必须是凹的。根据第二个规则,函数DrawPolygon()中绘制的多边形必须是凸的,因此要把所要绘制的模板图案分解成多个凸多边形。绘制凸多边形使用glBegin(GL_POLYGON)/glEnd()来完成,glBegin()与glEnd()之间用来指定所要绘制的凸多边形的顶点坐标,而这些顶点坐标可以通过滑块的纹理图片来得到。

1128419896.jpg


图5 使用模板缓存效果

5 结束语

利用OpenGL强大的图形功能,可以轻松地实现逼真的仿真模型效果。在此基础上,运用VC++.NET的MFC功能,可对OpenGL产生的模型进行控制,实现更为灵活的虚拟仿真效果。

参考文献

[1]费广正,芦丽丹,陈立新.可视化OpenGL程序设计[M].清华大学出版社,2001.

[2]尚游,陈岩涛.OpenGL图形程序设计指南[M].中国水利水电出版社,2001.

[3]Kruglinski D J.Visual C++技术内幕(第四版)[M].清华大学出版社,2001.