时间:2023-03-17 18:14:07
导言:作为写作爱好者,不可错过为您精心挑选的10篇程序设计论文,它们将为您的写作提供全新的视角,我们衷心期待您的阅读,并希望这些内容能为您提供灵感和参考。
随着计算机应用的普及,计算机应用专业也成了热门专业,而高级程序设计语言是计算机专业的一门必修课。在高级程序设计语言中,VisualBasic语言以其易学易用和功能强大,而且能够方便快捷地开发Windows应用程序等特征,而深受使用者欢迎。因此,其也作为中等职业学校的高级程序设计课的首选。VB是一门集知识和技能于一体、实践性很强的课程,要求学生既要学好理论知识,又要把握实际操作技能,同时,在进行软件开发时,要对用户需求及市场情况进行调研,再加上计算机软、硬件快速更新换代的特征,要求学生还要具有很强的自学能力和终身学习的思想。对于这些要求来说,传统的教学方法难以做到。而使用强调以职业活动为导向,以人的发展为本位的“行为导向教学法”将会较好的实现这些教学要求。本文拟就在中等职业教育的计算机程序设计(VisualBasic)教学中,如何运用“行为导向教学法”进行初步探索。
一、行为导向教学法的基本理论
“行为导向教学法”是在近几年从德国引进的现代的职业教育新模式,其目标层次是培养人的行为能力,方法层次是人的行为活动。即摘要:这种教育以行为为目标,教学以行为为导向,教学是学生积极参和的全面的教学,学习过程是学生同时用脑、心、手来进行学习的过程。
行为导向教学法具有很强的针对性,即是以职业活动为导向,以教会学生“学会学习、学会工作”为目标而开展教学活动,因此,对学习者来说,学习目的是十分明确,即现在的学习是为今后的职业服务。教学活动的开展,通常是围绕某一课题、新问题或项目开展,是以“学习任务”为载体,引导学生自主学习和探索的过程。整个教学过程为一个包括获取信息、制订计划、做出决定、实施工作计划、控制质量、评定工作成绩等环节在内的完整的行为模式。使用“行为导向教学法”,将能更好的培养学生的关键能力(专业能力、方法能力、社会能力、个性能力),以达到职业教育的“职业教育就是就业教育”的教学目标。
二、行为导向教学法在VisualBasic教学中的必要性和可行性
(一)必要性
现行的计算机专业类教材大多和其它学科式的教材一样,重视知识结构的系统性,教学内容大多以线性方式展开,适用于“循序渐进”的传统教学模式,以《VisualBasic程序设计》的教材为例,从语言基础、流程控制、过程和数组、窗体和控件、对话框设计、菜单、工具栏和状态栏设计等等,分章编排,在每一章的内容里,也同样按线性方式展开。假如,在教学中仍按传统的教学方法按章节讲授,势必降低的课程的综合性、实用性,也缺乏趣味性,这不但难以培养学生学习喜好,使得教学双方都陷入困境,而且,学生不知道如何在真实的情境中灵活地使用知识和运用技巧。这样的学习,是很难面对今后职业的。要改变这一现象的方法,比较成功的是运用以课题或项目来开展教学活动的行为导向教学法进行教学,在教学中,淡化知识的系统性和连贯性,更多关注的是知识之间的联系,在联系中学习知识、在综合运用中学习知识,使学生不仅学会了程序设计知识本身,又培养了学生运用程序设计的知识去解决实际新问题的能力,达到“学以致用”的教学目的。
(二)可行性
《VisualBasic程序设计》是一门实践性和操作性很强的课程,知识涉及许多抽象的术语,如摘要:类、对象、过程、语句、控件等等,还有大量的开发工具的使用。仅就VB的开发环境为例,其中就包含了摘要:窗体设计器、代码编辑器、对象浏览器、属性窗口、工程管理器、工具箱、菜单、工具栏等等。把握和熟悉它们的最好方法,就是在不断的结合实际的“案例”(案例教学法)或“课题”(项目教学法)的操作实践中去把握。在教学中,教师可以把课程内容包含在两到三个综合贴近实际的项目,给出案例,再把这个项目分成若干个小项目(或模块)。例如摘要:以开发一个“学生信息管理系统”为一个综合项目(教师首先给出案例演示,以引起同学们的关注),再分别以“登录窗口”、“查询窗口”等为小项目进行设计开发,学习相关的基础知识(如摘要:在设计“登录窗口”的项目中,学生可以把握“文本框、标签、命令按钮、属性设置、变量命名规则、变量定义、变量数据类型、变量的声明语句、赋值语句”等相关知识群)。学生在具有目标明确的项目驱动下,以“做中学”的方法进行学习,这样,不仅可以提高他们学习的主动性和学习乐趣,同时也培养了他们的关键能力。
二、“行为导向教学法”案例
行为导向教学法中的“项目教学法”是指师生以团队的形式共同实施一个完整“项目”的工作而进行的教学活动。通过在开展项目过程中有针对性的工作来培养学生的关键能力,非凡是独立工作能力、想象力、创新能力。项目教学法包括了计划、实施和检查及成果展示的全过程。它是由学生自己来完成整个过程的教学方法。以下是一个项目教学法的简案。
项目摘要:学生信息管理系统
(一)教学目标
1.培养学生运用VisualBasic知识解决实际新问题的能力;
2.培养学生独立学习和工作的能力;
3.培养学生和人合作的能力。
(二)项目的实施过程
三、需要重点注重的两个新问题
(一)教师角色的转换
在行为导向教学中,对教师提出了更高的要求。教师应是“双师型”的教师,老师的角色由传统的教学主导者转变为教学活动的引导者或主持人,在教学过程中,教师以咨询员、伙伴、朋友等角色出现在学生中,教学方法由注重“教法”转变为注重“学法”,为此,要完成教学任务,教师要付出更多的心血。
(二)项目设计的合理性
2测量分析电路设计
A/D转换与分析电路设计在图3中,A/D转换电路ADC0809的输入端IN0~IN7分别与图2中运算放大器的输出端V0~V7连接,将模拟信号转化为8位数字输出信号,并传送给单片机的D0~D7端口,由单片机进行分析运算。路模拟输出信号共需要4块ADC0809电路进行模数转换。单片机P0.0~P0.7端口接收ADC0809输出的8位数字信号后进行分析。
3电缆等效电阻检测程序设计
3.1标准等效电阻值确定
端子压接后电缆等效电阻的标准值因电缆长度不同而有差异。可采用预先设定标准值和自动确定标准值两种方法。对线径为0.4mm的铜芯线电缆,预先设置标准值RT标准可按照式(5)进行计算:RT标准=75+148•L(5)其中,L是电缆长度,单位为m;RT标准的单位是mΩ。自动确定标准值方法是以正常工艺在质量稳定情况下,将首根检验的压接端子的电缆作为样品,对32个芯线等效电阻进行自动检测对比,选取其中的最小值,然后乘以系数1.05作为标准值。
3.2自动设定标准值程序设计
标准等效电阻值存放于I2C存储器AT24C08中。检测程序设计多路通信电缆端子精密检测的主程序流程图如图5所示。以下为采集的主要函数,假设通道数为36路。
1通信协议的制定
协议是用来管理通信的法规,是网络系统功能实现的基础。由于DSP可以实现对网卡的直接操作,对应于OSI网络模型,网卡包含了物理层和数据链路层的全部内容,因此,规定了数据链路层上数据帧封装格式,就可以为基于DSP的局域网络中任意站点之间的通信提供具体规范。因为以太网是当今最受欢迎的局域网之一,在以太网中,网卡用于实现802.3规程,其典型代表是Novell公司的NE2000和3COM公司的3C503等网卡,所以研究工作中的具体试验平台是以DSP为核心构成的以太局域网,主要用于语音的实时通信,所使用的网卡为Novell公司的NE2000网卡。NE2000网卡的基本组成请见参考文献[2],其核心器件是网络接口控制器(NIC)DP8390。该器件有三部分功能:第一是IEEE802.3MAC(媒体访问控制)子层协议逻辑,实现数据帧的封装和解封,CSMA/CA(带碰撞检测功能的载波侦听多址接入)协议以及CRC校验等功能;第二是寄存器堆,用户对NE2000网卡通信过程的控制主要通过对这些寄存器堆中各种命令寄存器编程实现;第三是对网卡上缓冲RAM的读写控制逻辑。DP8390发送和接收采用标准的IEEE802.3帧格式。IEEE802.3参考了以太网的协议和技术规范,但对数据包的基本结构进行了修改,主要是类型字段变成了长度字段。所以,以DSP为核心的局域网内通信数据包基本格式如图1所示。
DSP读出数据包和打包从目的地址开始。目的地址用来指明一个数据帧在网络中被传送的目的节点地址。NE2000支持3种目的地址:单地址、组地址及广播地址。单地址表示只有1个节点可以接收该帧信息;组地址表示最多可以有64个字节接收同一帧信息;而广播地址则表示它可以被同一网络中的所有节接收。源地址是发送帧节点的物理地址,它只能是单地址。目的地址和源地址指网卡的硬件地址,又称物理地址。
在源地址之后的2个字节表示该帧的数据长度,只表示数据部分的长度,由用户自己填入。数据字段由46~1500字节组成。大于1500字节的数据应分为多个帧来发送;小于46字节时,必须填充至46字节。原因有两个:一是保证从目的地址字段到帧校验字段长度为64字节的最短帧长,以便区分信道中的有效帧和无用信息;二是为了防止一个站发送短帧时,在第一个比特尚未到达总线的最远端时就完成帧发送,因而在可能发生碰撞时检测不到冲突信号。NE2000对接收到的从目的地址字段后小于64字节的帧均认为是“碎片”,并予以删除。在数据字段,根据系统的具体功能要求,用户可以预留出若干个字节以规定相应的协议,以便通信双方依据这些字节中包含的信息实现不同的功能。
2基于DSP的网络通信程序设计
如果基于网络操作系统,用户可以利用一些软件对网络操作系统的支持,很容易地编写出优秀的网络通信程序,但这些程序必须依附于网络操作系统。而在DSP环境下,必须深入了解网络接口控制器(NIC)的工作原理[2],通过对网络直接编程,实现局域网内任意站点之间的通信而完全抛开网络操作系统。
DSP对网卡的通信过程控制就是DSP对DP8390中各种寄存器进行编程控制,完成数据分组的正确发送和接收。DP8390的所有内部寄存器都是8位,映像到4个页面。每个页面有16个可供读写的寄存器地址(RA=00H~0fH)。页面的选择由命令寄存器CA控制。第0页寄存器用于收发过程,第1页寄存器主要用于DP8390的初始化,第2页寄存器则用于环路诊断。DSP对寄存器的操作是将寄存器作为DSP的端口设备,其实际物理端口地址(PPA)为网卡基本I/O端口地址(BIOA)与寄存器地址(RA)之和(即PPA=BIOA+RA)。应注意的是,PPA与寄存器间并不存在一一对应关系,对PPA的读操作与写操作并不一定是对同一寄存器进行的,这种情况在第0页尤其明显。用户数据分组在DSP和网卡交互是通过网卡的数据端口实现的,既可以用DMA方式也可以用PIO方式读入数据分组或将数据分组送至网卡RAM缓冲区。在本系统中,DSP采用DMA方式对网卡进行数据读写。网卡的数据端口地址(NDPA)为网卡基本I/O地址(BIOA)加偏移地址10H(即NDPA=BIOA+10H)。
网卡通信过程控制可分为网卡初始化、接收控制和发送控制。下面分别予以讨论。
2.1网卡初始化
网卡初始化的主要任务是设置所需的寄存器状态,确定发送和接收条件,并对网卡缓冲区RAM进行划分,建立接收和发送缓冲环。具体过程请参阅参考文献[2]。需要说明的是,每一块网卡被赋予一个物理地址,以便通信站点的标识。这个物理地址存在网卡的PROM(存储地址为0000~0005H)六个单元中,在网卡初始化时,通过远程DMA读入DSP内存中,并送入网卡物理地址寄存器。在一步的意义在于:一方面,如果能正确读出网卡的物理地址,则说明网卡硬件基本没有问题,网卡的上电复位和DSP对网卡的初始化顺利通过;另一方面,这个物理地址可以用于DSP网络系统中的点名、包的过滤丢弃等服务,也就是说,在链路层根据数据帧携带的源地址和目的地址确定数据报从哪里来,是否接收或丢弃。网卡初始化时另一个重要的工作就是接收缓冲环的设置,为了有效利用缓冲区,NIC将接收缓冲区RAM构成环形缓冲结构,如图2所示。
接收缓冲区RAM分成多个256字节的缓冲区,N个(N最大为256)这样的缓冲区通过指针控制链接成一条逻辑上的缓冲环。缓冲环的开始页面地址存入PSTART寄存器,环页面结束地址存入PSTOP寄存器。PSTART和PSTOP确定了接收缓冲环的大小和边界。为便于缓冲环读写操作,还需要2个指针:当前页面指针CURR和边界指针BNRY。CURR确定下一包放在何处,起着缓冲环写页面指针作用;BNRY指向未经DSP取走处理最早到达的数据包起始页面,新接收的数据包不可将其覆盖,起着缓冲环读页面指针的作用。也就是说,CURR可以告诉用户网卡接收的数据分组当前放到了什么位置,而BNRY则用于确定DSP读缓冲环到了什么地方。由于接收缓冲区为环形结构,BNRY和CURR相等时,环缓冲区可能满也可能空。为了使NIC能辨别这两种状态,规定当BNRY等于CURR时,才认为环缓冲区满;当缓冲区空时,CURR比BNRY指针值大1。因此,初始化时设置:BNRY=PSTART,CURR=PSTART+1。这时读写指针不一致,为了保证正确的读写操作,引入一软件指针NEXTPK指示下一包起始页面。显然,初始化时NEXTPK=CURR。这时,缓冲环的读指针对NEXTPK,而BNRY只是存储分组缓冲区的起始页面边界指示,其值为NEXTPK-1。
2.2接收控制过程
DSP完成对DP8390的初始化后,网卡就处于接收状态,一旦收到分组,就自动执行本地DMA,将NIC中FIFO数据送入接收缓冲环,然后向主机申请“数据分组接收到”中断请求。DSP如果响应中断,则启动网卡远程DMA读,将网卡缓冲区中的数据分组读入学生机存储区,然后对接收缓冲环CURR、NEXTPK、BNRY指针内容进行修改,以便网卡能从网上正确接收后续分组。DSP响应网卡接收中断后,接收控制过程如下:
①设置远程DMA的起始地址;RSAR0=00H,RSAR1=Nextpk。
②设置远程DMA操作的字节数,这个长度在46~1500字节范围内根据具体要求自己确定。
③0AH送命令寄存器CR,启动远程DMA读。
④从网卡数据端口依序读入数据分组,注意,最先读入的4字节非数据分组内容,第1字节为接收状态,第2字节为下一包页地址指针,3与4字节为接收字节数。第2字节内容应该送入Nextpk,其它字节根据用户要求处理。
⑤修改边界指针BNRY=Nextpk-1。
⑥清除远程DMA字节数寄存器RBCR0和RBCR1。
2.3发送控制过程
DSP先执行远程DMA写操作,将内存中的数据分组传至网卡发送缓冲区,然后启动发送命令进行数据分组发送。发送控制过程如下:
①设置远程DMA的起始地址为网卡发送缓冲区起始地址;
②设置远程DMA操作的字节数;
③12H送命令寄存器CR,启动远程DMA写;
④依序送出数据分组至网卡发送缓冲区;
⑤清除远程DMA字节数寄存器;
⑥设置发送字节数寄存器TBCR0和TBCR1;
⑦12H送命令寄存器CR,启动数据分组发送。
3发送方发送频率的控制
发送方发送频率的正确控制主要保护两点:一是有一个最小发送时间间隔,否则会因为接收方不能及时接收而导致系统瘫痪;二是发送频率能够足具体的功能实现要求。譬如在语音的实时通信中,发送频率就取决于声卡的采样频率。在8kHz采样频率时,声卡每秒钟采样8000字节,采用1024字节需用时128ms,如果通信协议规定发送1次传送1024字节有效数据,则必须每128ms发送一次才能保证缓冲区有新数据待发送,也才能保证接收方有新数据播放。128ms是一个理论计算数值,在实际的操作中采样速度和发送频率之间总是不能完全匹配,而存放数据的缓冲区大小是有限的,如果没有良好的控制技巧来实现正确发送,就会造成声音抖动和延时。解决的办法是双缓冲技术和双指针控制,并且根据采样速度和发送频率之间的匹配情况送入不同的发送通信进行处理后发送。正确发送的含义有两方面,一是每次发送的都是新数据,二是能满足接收方总在播放新数据的需求。
4接收方防止数据包的丢失
2高职Java程序设计课程教学的改革
2.1教学内容的改革
高职教育更侧重于将学生培养成能够满足工作岗位或职业需求、掌握相应技能的应用型人才,因此,改革教学内容是非常有必要的。改革教学内容就是改变传统的理论教学,引入适量的案例,将基本理论的讲授穿插于案例教学中。需要特别注意的是,选择恰当合理的案例是非常重要的,它的质量能够直接影响到最终的教学效果。因此,教师要根据学生认知的特点选择具有适用性及代表性的案例,而且这些被选择的案例必须能够包含Java程序设计中的大部分知识,这些案例既区别于课堂上的举例,但又和它们具有一定的联系。为了能够很好地展开案例教学,教师在课前需要对案例教学进行周密详细的安排,主要包括四个方面,它们分别是发放案例素材、组织案例实施、区分案例分析中的理论分析以及操作分析、安排处理案例教学中涉及到的外延知识。案例教学能够在课堂上很好的结合理论与实践,促进学生综合能力的提升。学生带着问题去分析案例,在这个过程中教师对涉及到的相关理论知识进行讲授,这种方式能够帮助学生更好地理解知识。对案例进行分析的过程不仅能够使学生拓宽知识面,掌握分析问题的技巧,还能够帮助学生将理论运用于实践,更好地消化吸收所学知识。因此,相比传统的理论教学,案例教学这种教学方法更够满足当今社会对应用型人才的需求。
2.2教学方法的改革
当今社会团队协作能力是非常重要的,因此,改革教学方法最主要的一个途径就是实行小组教学。所谓小组教学就是很据自愿或者协商的原则,将全班学生平均划分成几个小组,由小组成员共同推选出一个成员作为组长。在课堂上,首先教师需要在对典型案例进行讲解的过程中穿插对Java语言的介绍,帮助学生更好地理解进而接受理论知识,并且深入了解Java语言面向对象的特性。然后教师通过为每个学习小组安排编程的任务来使学生对案例进行分析,并且分析讨论后每个小组都要确定出最终的解决方案,由教师来点评这些方案。为了能够使学生高效率的完成规定任务,教师要在分析讨论过程中对学生提出相应的技术要求及纪律要求,并设定一个恰当的完成期限。这种教学模式充分体现了学生学习的自主性,彰显了学生课堂的主体地位以及突出了教师协助引导的作用。小组教学的教学模式可以使学生进行不同的思想交流,擦出智慧的火花,正如萧伯纳所说“如果我有一个苹果,你有一个苹果,互相交换,还是你有一个苹果,我有一个苹果。但是我有一种想法,你有一种想法,交换一下,双方就都有了两种思想。”这就说明了通过小组交流,学生思维会更加活跃,从而产生更优的思想。通过小组教学,不仅可以提升学生对理论知识的认知度,培养团队合作的能力,还能够提升学生分析、处理、解决问题的能力。此外,在小组教学的过程中,教师能够迅速接收到来源于学生的反馈信息,比如反馈分析案例过程中遇到的问题等信息,通过这些反馈信息,教师能够及时的采取相应措施来解决问题,从而实现教学相长。
2.3考核方式的改革
对教学成果进行考核对无论是教还是学都能做出恰当的评价,目前我国高职院校中通常采取考核这一手段来对教学的效果进行检验。在传统的教学模式下,通常采取卷面考试来进行考核,而且最终结果往往是由一次考试的成绩来评定的,也就是说,无论学生平日里表现多好,但如果在作为最终考核的那次考试中发挥失常,那么就会在一定程度上否认这个学生的学习能力。而且这种考核方式并不能够对学生的能力、知识以及技能做到真实的反映。由此看来,为了能够对学生的学习做出恰当合理的评价,改革考核方式是非常有必要的。这就要求高职院校要制定一个科学的评价标准,重点突出对学生知识应用能力的培养。在对高职Java程序设计课程学习进行考核时,可以通过两个方面来展开考核工作,相应地,学生总成绩也由两部分组成,一部分是综合能力考核成绩,另一部分是平时课堂表现成绩。具体来讲,一方面,通过案例教学,教师要求每个小组在对案例分析完成之后,做出案例的分析报告,在此基础上,综合小组成员的意见和建议,为假定的任意一个应用领域或虚拟企业设计一个信息管理系统,然后模拟其运行环境,最后进行编码或者程序设计。总之,就是给予学生一个展示自我知识、技能、操作等综合能力的机会,这种考核方式能够使学生更加牢固、系统的掌握所学的理论知识,这方面的考核成绩占据较大的比重,在总成绩中通常占据60%的比例。另一方面,也就是占据总成绩40%的平时成绩,具体来讲,就是在平时教学过程中,教师要密切关注课堂小组讨论中每位学生的表现,并且加以记录,给出相应的分数。此外,在本门学科结束学习后,教师需要组织每个小组进行小组内成员间的彼此评价,相互打分。最后,教师通过对这两小部分的成绩进行综合的评定,给出每个学生最终的平时课堂表现成绩。
1.1设计原理
为实现嵌入式田间图像视频采集,主控芯片选择使用比较广泛的S3C2440芯片,摄像头采用芯片为中星微ZC301的USB摄像头,把采集到的植物视频信息传输到主控芯片中。主控芯片包括把采集的视频信息显示到LED触摸屏上,还要把采集到的信息传输到PC机中。大田视频采集模块总体结构如图1所示。图1大田视频采集模块总体结构图软件方面包括USB摄像头的驱动程序、视频采集程序、LED实时显示程序网络传输程序的设计、调试、烧写等操作。
1.2主要研究的内容
1)对ARM嵌入式Linux的内核,Bootloader、YAFFS根文件系统的制作和移植,即完成软件平台的搭建;2)中星微ZC301的USB摄像头驱动程序的设计;3)模块的视频采集程序的设计;4)设计驱动LED,来显示采集到视频信息的程序;5)设计TCP网络传输程序,把视频信息发送出去;6)把采集到的视频图像显示到PC虚拟机上。
2、总体设计
2.1平台设计
2.1.1 BootLoader制作和移植首先按下任意键,使ARM9的程序运行停止在如图2所示的在DNW软件上出现主选择菜单界面;接着选择下载到flash,即选择‘1’,使用USB下载;在DNW软件上出现有关闪存的各个存储区间的情况。在上一步完成的基础上,再选择FLb.bin要烧写到NAND闪存中的位置,即选择‘0’,烧写到NAND闪存中的boot的位置;然后在DNW软件界面下执行配置选项中的操作执行指令,来进行下载地址、COM口和波特率设置;在DNW软件上点击USBPort选项中的传输操作,找到要烧写FLb.bin的位置,选中FLb.bin文件;文件传输完成后即完成了BootLoader的移植。
2.1.2 系统内核剪裁、制作和移植Linux内核的移植和引导加载程序的烧写过程几乎是相同的,添加内核的映像文件和BootLoader的移植都是相同的。也就是说,内核是下载到NAND闪存的kernel位置;内核移植时会出现移植进度条;移植完成后出现的和BootLoader的移植出现的提示一样。到此,Linux内核的移植就完成了。Linux内核配置对话框如图3所示。
2.1.3 FAFFS根文件系统的创建和烧写过程1)使用目录创造命令创造根文件系统的目录,并创建在usr目录下的bin、dev、etc等目录,把根文件系统的框架搭建起来;2)创造根文件系统的设备文件,进入到dev目录下使用创造命令来完成;3)安装etc,进入到etc目录下进行解压etc.tar.gz;4)进入到内核目录下使用模块编译命令来编制内核模块;5)使用模块安装命令对模块进行安装;6)使用配置命令对其进行配置,编译命令进行编译,安装命令进行安装;7)进入到根文件目录下使用ln-s命令来进行链接,重新再编译内核;8)将编译生成的内核映像文件通过USB传输到开发板的根文件系统中。
2.2软件设计
2.2.1 摄像头驱动程序设计
实现USB设备的即插即用功能的函数是摄像头探测函数,函数名称是sp_probe。该驱动程序中的数据传输模块使用takelet来实现对数据的同步快速传递,此函数对图像数据进行解码使用的是spcode.c程序。数据传输模块函数的具体名称是sp5_init_isoc,并且在sp5_open函数中挂有该函数的入口点。打开设备是同步传输数据开始的标志,这里实现数据传输的函数是sp_m_data,它把数据传送给驱动程序,驱动程序对数据的访问使用的是轮询法。Linux中的USB器件通过系统的USB层来操作下层硬件,流程图如图4所示。
2.2.2 模块视频采集程序
本系统的视频采集程序是基于V4L开发的,主要实现图像采集设备的初始化、读取和关闭等,基本操作流程如图5所示。
3、大田视频采集模块的安装与调试
3.1大田视频采集模块安装执行该命令要在该软件文件所在的目录下,将视频采集模块和PC虚拟机连接起来。这样在PC虚拟机上就会显示出视频图像,如图6所示。
3.2大田视频采集模块现场调试在齐齐哈尔嫩江大桥以北的农田里,对种植的土豆进行试验。模块调试如图7所示。图7模块调试一触摸屏LED和虚拟机显示图像不清晰,是因为帧的大小等参数设置得小,修改后图像较原来清晰些;触屏和虚拟机图像显示不连贯是因为其显示程序中延时设置太大,以及内核需要优化小点。大田视频采集模块的对农作物视频采集稳定,触屏的视频图像显示非常清晰,且以非常高的质量把采集到的视频图像传输到了PC机上(见图8),在其上显示的视频图像清晰连贯,能对农作物进行非常有效的实时监测;操作人员能够从其中迅速获得农作物的自身生长发育情况和是否有病虫害等信息,而且大田的农作物视频信息采集受阳光的影响也很小。本次试验非常成功。图8PC机显示的视频图像
(1)程序应最大限度的调用前期设计数据,减少人工输入,程序需通过制作数据接口,从前期设计软件中有选择性的调入全桥总信息及每个墩台的墩台号、墩台里程、基础类型、初始桩长、基顶基底标高、基础尺寸、桩基布置等信息,减少设计者重复输入,同时降低操作错误率。(2)桩基展开布置时要求对每根桩的数据进行操作,现有的每个桥墩桩基数据中桩基数据需通过一定转换,以图形形式清晰明了的展现出来,同时还能够提供一定格式的数据供其他程序进行计算等。(3)设计者对全桥每个桥墩基础数据修改编辑后,程序需将数据存储起来,以备进行下一步操作和下次查询。但由于全桥信息量较大,需研究有效的数据存储形式,以便设计者能快速调用和修改。
1.2数据在不同的坐标系进行坐标转换
(1)在程序默认桩坐标、地质提供的桩坐标以及桥梁桩基计算程序桩坐标3者之间进行转换,提供给设计者便捷的修改方式,满足各种不同的坐标系统之间进行灵活的的转换。(2)地质展开剖面图的不确定性决定了基础展开形式的多样性,桩与桩之间的相互位置关系变化多样,程序应能适用各种不同的情况,快速计算各桩位之间的相互位置关系。
1.3程序的绘图及读图功能
(1)根据地质剖面图的展开路径绘制基础展开布置图时,程序通过读取地质剖面图中的信息,校核地质剖面图的比例,定位每个钻孔的位置,根据每根桩与各钻孔之间的位置关系来绘制基础展开布置图。展开图能按照一定的纵横向比例绘制,每个桩位标明相应的编号等。程序应根据地质剖面图的形式,灵活采用单点定位和多点定位,同一桩基灵活拆分,提供多样的绘图方式。(2)程序需对地质柱状图逐孔进行识别提取各地层信息后,根据专业要求将地层详细的描述转换到地质剖面图中,完善各地层的地质描述。根据纵横向比例将地层名称、承载力值等描述添加到地质剖面图中。(3)程序应有完善的图面清理及图面排版布局功能,以及桩长反读及校核功能便于进行后续计算等。
1.4桥梁基础的数量计算及汇总功能
(1)程序应根据全桥工程数量计算模板衍生出单墩数量计算模板进行展开后的桩基计算,以统一数量计算格式,提高程序自动转换、批量处理效率。(2)根据每根桩的钻孔资料进行各钻孔土层进行分析,归类汇总各土层的数量,尽可能精确计算单墩的基础数量。(3)程序应将全桥各桥墩的单墩基础数量进行汇总,生成全桥总数量。
2关键技术
2.1数据接口及转换
(1)基础的设计需要前期数据的调出量大,种类杂,数据调入调出时尽量减少对象中数据转换,采用数组进行内部运算完成后,再将运算结果与表格进行对接,将对表格对象的操作次数降低到最少,提高运行速度。(2)设定3套坐标系统进行灵活的转换,将数据图形化,直观化,如图1所示。桩基础设计中,地质桩号又能根据实际钻孔路径任意编排,桩间距能迅速计算导出,对部分数据进行监控,当数据修改时,能迅速响应,调出数据,展示图形,操作相当方便,显示也很直观明了。程序计算完成后,能自动进行存储,数据更新及时,灵活方便。任意路径展开桩基的计算,如图2所示。对于桩基础,程序处理流程如图3所示。
2.2桩基坐标转换的实现
前期的数据收集后,通过校核补齐后转换成程序默认的坐标系统,桩号顺序按照从上到下和从左到右的顺序编排的开来,这样编排符合一般的标号习惯。桥梁设计软件中桩排列一般是按x坐标从小到大,然后y坐标从小到大的顺序排列的,这种排列方式便于程序计算。地质专业进行地质钻孔时,形成相应钻孔顺序和坐标系统。于是程序内部需要建立3套坐标系统的相互关系网,以便能快速在各坐标系统之间进行转换,快速与外部数据进行导入导出操作。程序内部各坐标之间的转换关系如图4所示。绘制展布图时,承台、桩及地层信息等在CAD图中的纵横向定位是比较棘手的问题。纵向定位主要有每根桩的桩顶高程、桩长、桩底高程、地层描述信息等,横向定位主要是桩与钻孔之间关系、桩与桩之间的关系定位等。纵向定位关键是确定定位标尺后计算高程标定纵向元素,横向定位的关键是定位钻孔按绘图比例计算距离在定位桩位。桩基纵向定位的基本的流程如图5所示。
2.3添加地质钻孔信息
地层信息由地质钻孔柱状图提取后展示到地质剖面图中前,需要对地质柱状图进行分析过滤提取各地层信息,再在地质剖面图中定位到钻孔编号后根据地层上下界面高程纵向定位到各地层中去。添加地质钻孔信息后如图7所示。2.5单墩桩基及全桥桩基工程数量的计算计算单墩桩基工程数量时,程序通过全桥工程数量表衍生出单墩工程数量表,保持基础工程数量计算相关工作表中各项目的完整,利用其固定性而又适应其灵活性,继承全桥工程数量表的计算方法和特点。设计者对单墩工程数量计算完成后,程序将各墩数量汇总起来,再经过设计者复核,程序再将其与全桥工程数量整合在一起。其间的计算步骤均允许设计者参与修改,同时程序进行逻辑性校核等。汇总各墩数据到全桥工程数量表中的流程图如图8所示。
1引言
遗传算法是模拟生物在自然环境中的遗传和进化过程而形成的一种自适应全局优化概率搜索算法。总的说来,遗传算法是按不依赖于问题本身的方式去求解问题。它的目标是搜索这个多维、高度非线性空间以找到具有最优适应值(即最小费用的)的点[1]。
基本遗传算法是一个迭代过程,它模仿生物在自然环境中的遗传和进化机理,反复将选择算子、交叉算子和变异算子作用于种群,最终可得到问题的最优解和近似最优解。
2遗传算法程序设计改进比较
2.1基本遗传算法对TSP问题解的影响
本文研究的遗传算法及改进算法的实现是以C++语言为基础,在Windows2000的版本上运行,其实现程序是在MicrosoftVisualStadio6.0上编写及运行调试的。
1)遗传算法的执行代码
m_Tsp.Initpop();//种群的初始化
for(inti=0;i<m_Tsp.ReturnPop();i++)
m_Tsp.calculatefitness(i);//计算各个个体的适应值
m_Tsp.statistics();//统计最优个体
while(entropy>decen||variance>decvar)//m_Tsp.m_gen<100)
{
//将新种群更迭为旧种群,并进行遗传操作
m_Tsp.alternate();//将新种群付给旧种群
m_Tsp.generation();//对旧种群进行遗传操作,产生新种群
m_Tsp.m_gen++;
m_Tsp.statistics();//对新产生的种群进行统计
}
2)简单的遗传算法与分支定界法对TSP问题求解结果的对比
遗传算法在解决NPC问题的领域内具有寻找最优解的能力。但随着城市个数的增加,已没有精确解,无法确定遗传算法求解的精度有多高。一般情况下,当迭代代数增大时,解的精度可能高,但是时间开销也会增大。因此可以通过改进遗传算法来提高搜索能力,提高解的精度。
2.2初始化时的启发信息对TSP问题解的影响
1)初始化启发信息
在上述实验算法的基础上,对每一个初始化的个体的每五个相邻城市用分支界定法寻找最优子路径,然后执行遗传算法。
2)遗传算法与含有启发信息的遗传算法求解结果的对比
当城市数增至20个时,用分支定界法已经不可能在可以接受的时间内得到精确的解了,只能通过近似算法获得其可接受的解。试验设计中算法的截止条件:固定迭代1000代。表2中的平均最优解为经过多次试验(10次以上)得到的最优解的平均值,最优解的出现时间为最优解出现的平均时间,交叉操作次数为最优解出现时交叉次数的平均值。
表220个城市的TSP问题求解结果数据
算法交叉操作
次数最优解
出现时间平均
最优解
简单遗传算法80244.479.4s1641.8
含初始化启发信息的GA79000.237.4s1398.9
从表2中可以看出,当初始种群时引入启发信息将提高遗传算法的寻优能力。同时缩短了遗传算法的寻优时间和问题的求解精度。
2.3交叉算子对TSP问题解的影响
1)循环贪心交叉算子的核心代码
for(i=1;i<m_Chrom;i++)
{
flag=0;
city=m_newpop[first].chrom[i-1];//确定当前城市
j=0;
while(flag==0&&j<4)
{
sign=adjcity[city][j];//adjcity数组的数据为当前城市按顺序排列的邻接城市
flag=judge(first,i,sign);//判断此邻接城市是否已经存在待形成的个体中
j++;
}
if(flag==0)//如果所有邻接城市皆在待扩展的个体中
{
while(flag==0)
{
sign=(int)rand()/(RAND_MAX/(m_Chrom-1));//随机选择一城市
flag=judge(first,i,sign);
}
}
if(flag==1)
m_newpop[first].chrom[i]=sign;
}
2)问题描述与结果比较
下面笔者用经典的测试遗传算法效率的OliverTSP问题来测试循环贪心交叉算子的解的精度和解效率。OliverTSP问题的30个城市位置坐标如表3所示[2]。
从表4、图1中可以看到,贪心交叉算子大大提高了遗传算法的寻优能力,同时也降低了交叉操作次数。在多次试验中,贪心交叉算子找到的最优解与目前记载的最佳数据的误差率为2.7%。而部分匹配交叉算子找到的最优解与目前记载的最佳数据的误差率高达7%。从而可以得到交叉算子对于遗传算法
2.4并行遗传算法消息传递实现的核心代码
1)主程序代码
//接收各个从程序的最优个体
for(i=0;i<slave;i++)
{
MPI_Recv(Rchrom[i],chrom,MPI_UNSIGNED,MPI_ANY_SOURCE,gen,MPI_COMM_WORLD,&status);
}
//计算接收各个从程序的最优个体的回路距离
for(i=0;i<slave;i++)
{
fitness[i]=0.0;
for(intj=0;j<chrom-1;j++)
fitness[i]=fitness[i]+distance[Rchrom[i][j]][Rchrom[i][j+1]];
fitness[i]=fitness[i]+distance[Rchrom[i][0]][Rchrom[i][chrom-1]];
}
//找到最优的个体并把它记录到文件里
for(i=0;i<slave;i++)
{
if(1/fitness[i]>min)
{
sign=i;
min=1/fitness[i];
}
}
fwrite(&gen,sizeof(int),1,out);
for(i=0;i<chrom;i++)
fwrite(&Rchrom[sign][i],sizeof(unsigned),1,out);
fwrite(&fitness[sign],sizeof(double),1,out);
//每九代向从程序发送一个最优个体
if(gen%9==0)
MPI_Bcast(Rchrom[sign],chrom,MPI_UNSIGNED,0,MPI_COMM_WORLD);
2)从程序代码
//将上一代的最优个体传回主程序
MPI_Send(Rchrom1,chrom,MPI_UNSIGNED,0,gen,MPI_COMM_WORLD);
//每九代接收一个最优个体并将其加入种群中替换掉最差个体
if(gen%9==0)
{
PI_Bcast(Rchrom2,chrom,MPI_UNSIGNED,0,MPI_COMM_WORLD);
Tsp.IndiAlternate(Rchrom2);
}
//进行下一代的计算
Tsp.Aternate();
Tsp.Generation();
Tsp.Statistics();
3)并行遗传算法的性能
笔者在MPI并行环境下,用C++语言实现了一个解决TSP问题的粗粒度模型的并行遗传算法。该程序采用的是主从式的MPI程序设计,通过从硬盘的文件中读取数据来设置染色体长度、种群的规模、交叉概率和变异概率等参数。试验环境为曙光TC1700机,测试的对象是OliverTSP问题的30个城市的TSP问题。
正如在测试串行遗传算法所提到的数据结果,并行遗传算法也没有达到目前所记录的最好解,但是它提高了算法的收敛性,并行遗传算法的收敛趋势如图2所示[4]。
图2遗传算法的收敛过程
3结束语
本文通过对基本遗传算法的不断改进,证明了添加启发信息、改进遗传算子和利用遗传算法固有的并行性都可以提高遗传算法的收敛性,其中对遗传算法交叉算子的改进可以大大提高遗传算法的寻优能力。
参考文献
[1]刘勇、康立山,陈毓屏著.非数值并行算法-遗传算法.北京:科学出版社1995.1
对于大多数课程而言,从宏观上将课程知识点及其关联讲授给学生非常必要,这便于学生更加系统深刻地理解所学内容。作为教材讲解C语言程序设计的知识点结构。知识点之间的关联可以层层细化,教师首先从宏观上给学生介绍C语言程序的整体组成结构。教师对涉及的知识点进行归类,共包含预处理命令、数据类型、运算符、语句和函数等5部分,从宏观上梳理C语言与程序设计课程的知识点是非常必要和重要的,这样可以避免学生“只见树木,不见森林”,最后只学到一堆零散的知识点,只有从宏观上把握各个知识点在知识体系中的位置和作用,才能学得深、记得牢。对于程序语言课程,如果仅仅介绍语法的运用,学生往往对知识点理解不深刻。我们在教学实践中的体会是:在讲解C语言语法的基础上,适当地剖析编程语言在计算机中的运行机制,会让学生的理解更加透彻。因此,我们的课堂教学方法分为如下两部分。
1)课件讲解。课件讲解包括两部分,即知识点要点总结和知识点运行机制剖析。知识点要点总结就是告诉学生该知识点如何使用;而知识点运行机制剖析则告诉学生该程序在计算机内存中的执行过程。由于绝大部分高校在开设C语言程序设计之前都会开设计算机文化基础等课程,因此学生有足够的计算机基础知识来理解C语言程序的运行机制。
2)实例演示。作为一门编程语言,C语言需要在实践中理解和掌握,因此,课堂教学中,在具体的编程环境(如VC++6.0)下演示十分必要。通过在具体的软件环境下编程,告诉学生应该做什么和不应该做什么,并总结该知识点的注意事项。相比传统的脱离编程环境,只在PPT或黑板上进行板书的教学模式,该方法的教学效果要好得多。在课堂教学中,具体的教学步骤如下:①使用PPT或者板书列出该知识点的注意要点;②在编程环境(如VC++6.0)下演示该知识点的用法,给出正确的和错误的使用方法,并进行对比;③通过幻灯片动画或Flas等形式演示程序在计算机内存中的执行过程,让学生更加深刻地理解程序的运行机制。
3)教学难点与重点——“复合知识点”。从C语言的教学内容来讲,数组、函数和指针是教学的重点章节,这些章节之间相互关联的部分又是重点中的难点,如数组和函数结合,数组名做函数参数,数组和指针结合,指向数组的指针变量,函数和指针结合,指向函数的指针变量等。在教学过程中要反复强调各个知识点的注意事项,如果基本知识点能够理解透彻,上述难点内容也就迎刃而解了。
1.2上机实践教学
在实践教学中,教师可以通过实际教学案例循序渐进地强化学生对C语言知识点的理解。上机实践的教学内容通常分为两部分:基本知识点练习和综合训练。首先通过基本知识点的练习,让学生掌握该知识点的使用,即巩固课堂所学内容;然后通过一个综合性的大作业,训练学生综合应用C语言知识点的能力,例如,通过编写“学生课程成绩统计系统”考查学生对数组、结构体、指针、函数、文件等知识的综合掌握情况。对于初学编程语言的学生,往往没有养成良好的编程习惯,出错的可能性较大,而出错之后进行调试又将耗费较长的时间,这势必对学生的学习热情产生负面影响。因此,一开始就给学生制定科学的编程步骤和规范,使学生养成良好的编程习惯,将大大减少程序出错的可能。下面是按照上述五步编写的一个完整的C语言程序,用来比较两个整数的大小。按照上述五步进行编程,经过一段时间的训练之后,学生出现语法错误的可能性大大降低,此时学生更多的精力将集中在程序算法的设计和实现上。
1.3考试形式
对于C语言程序设计的考核方式,我们采用知识点考核和编程实践相结合的方式。知识点考核偏重于C语言基本语法,用于检验学生对知识点的掌握是否全面,此项考核约占总成绩的40%;编程实践考核用于检验学生的实际动手能力,学生将在规定的时间内根据题目在机器上编程,此项考核约占总成绩的60%。为了实现知识点的考核,我们将考试与计算机二级C语言上机考试紧密结合,采用题库平台进行上机考试,学生直接在机器上答题并提交,知识点考核多采取客观题,如填空题、程序修改题以及读程序题等,编程题在实战编程中考核。C语言程序设计课程的重要特点就是实践性强,学习该课程的目的就是为了编写程序。因此从考试的角度讲,进行编程实践是最合适的方式,通过上机编程来考核学生的学习情况也是最公正和客观的方式。
2C语言程序设计教学实践结果分析
中国矿业大学(北京)每年都有40多个班级同时开设C语言程序设计课程,因此该课程教学质量的高低将直接影响全校理工科学生对C语言的理解和掌握。中国矿业大学(北京)C语言程序设计教学团队经过长期的探索总结出一套行之有效的C语言教学方法,我们将上述方法在学校越崎实验班中进行了试点。如图2所示,采用上述教学法的越崎实验班的C语言程序设计课程考试成绩要明显好于其他班级,其中90分以上的学生占10.7%,80分以上的学生占总人数的53.6%。另外,学生的学习积极性比采用上述方法前得到明显提高,很多学生都对计算机编程产生了浓厚兴趣,实践证明我们提出的上述方法是行之有效的。
要拥有一台Pentium90以上、16MBRAM、520MB以上硬盘容量的PC机以及一台43cm以上的大屏幕监视器和一块OpenGL三维图形加速卡组成的系统,就能与图形工作站相媲美,但价格却便宜数十倍。
本文作者一直从事计算机图形应用开发工作。原来是在SGI工作站上利用OpenGL开发图形程序,后来又首先在国内第一块三维图形加速卡AGC-3D上基于WindowsNT的VisualC++2.0环境下继续进行开发。在开发过程中,同一OpenGL程序几乎不用修改就能在两个平台间来回移植,效果甚好。
一、OpenGL特点及功能
OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,能十分方便地在各平台间移植。
OpenGL具有七大功能。
(1)建模OpenGL图形库除了提供基本的点、线、多边形的绘制函数外,还提供了复杂的三维物体(如球、锥、多面体、茶壶等)以及复杂曲线和曲面(如Bezier、Nurbs等曲线或曲面)绘制函数。
(2)变换OpenGL图形库的变换包括基本变换和投影变换。基本变换有平移、旋转、变比和镜像四种变换,投影变换有平行投影(又称正射投影)和透视投影两种变换。
(3)颜色模式设置OpenGL颜色模式有两种,即RGBA模式和颜色索引(ColorIndex)。
(4)光照和材质设置OpenGL光有辐射光(EmittedLight)、环境光(AmbientLight)、漫反射光(DiffuseLight)和镜面光(SpecularLight)。材质是用光反射率来表示。场景(Scene)中物体最终反映到人眼的颜色是光的红绿蓝分量与材质红绿蓝分量的反射率相乘后形成的颜色。
(5)纹理映射(TexureMapping)利用OpenGL纹理映射功能可以十分逼真地表达物体表面细节。
(6)位图显示和图像增强图像功能除了基本的拷贝和像素读写外,还提供了融合(Blending)、反走样(Antialiasing)和雾(fog)的特殊图像效果处理。
(7)双缓存(DoubleBuffering)动画双缓存即前台缓存和后台缓存,简而言之,后台缓存计算场景、生成画面,前台缓存显示后台缓存已画好的画面。
此外,利用OpenGL还能实现深度暗示(DepthCue)、运动模糊(MotionBlur)等特殊效果。
二、OpenGLforWindowsNT图形库
OpenGL图形库一共有100多个函数。其中核心函数有115个,它们是最基本的函数,其前缀是gl;OpenGL实用库(OpenGLutilitylibrary,GLU)的函数功能更高一些,如绘制复杂的曲线曲面、高级坐标变换、多边形分割等,共有43个,前缀为glu;OpenGL辅助库(OpenGLauxiliarylibrary,GLAUX)的函数是一些特殊的函数,包括简单的窗口管理、输入事件处理、某些复杂三维物体绘制等函数,共有31个,前缀为aux。
此外,还有六个WGL函数非常重要,专用于OpenGL和WindowsNT窗口系统的连接,其前缀为wgl,主要用于创建和选择图形操作描述表(renderingcontexts)以及在窗口内任一位置显示字符位图。这些功能是WindowsNT对OpenGL的唯一补充,见表1所示。
表1管理图形操作描述表的WGL函数
另外,还有五个Win32函数用来处理像素格式(pixelformats)和双缓存。由于它们是对Win32系统的扩展,因此不能应用在其他OpenGL平台上,见表2所示。
表2管理像素格式Win32函数
三、OpenGLforWindowsNT程序设计
OpenGLforWindowsNT的程序设计与OpenGLforUNIX的程序设计有一点小区别,关键就在于如何将OpenGL与不同操作系统下的窗口系统连接起来。如果调用OpenGL辅助库窗口管理函数,则不用考虑这些问题。下面将主要介绍在WindowsNT下OpenGL的程序设计关键。
1.图形操作描述表
在WindowsNT下窗口程序必须首先处理设备描述表(DeviceContexts,DC),DC包含许多如何在窗口上显示图形的信息,即指定画笔和刷子的颜色,设置绘图模式、调色板、映射模式以及其他图形属性。同样,OpenGLforWindowsNT的程序也必须使用DC,这与其他Windows程序类似。但是,OpenGLforWindowsNT必须处理特殊的DC图形操作描述表,这是DC中专为OpenGL使用的一种。一个OpenGL应用图形操作描述表内有OpenGL与WindowsNT窗口系统相关的各种信息。一个OpenGL应用首先必须创建一个图形操作描述表,然后再启动它,最后在所定义的窗口内按常规方式调用OpenGL函数绘制图形。
一个图形操作描述表不同于其他DC,它们调用每个GDI函数都需要一个句柄,而图形操作描述表方式下只需一个句柄就可任意调用OpenGL函数。也就是说,只要当前启用了某个图形操作描述表,那么在未删除图形操作描述表之前可以调用任何OpenGL函数,进行各种操作。
2.像素格式
在创建一个图形操作描述表之前,首先必须设置像素格式。像素格式含有设备绘图界面的属性,这些属性包括绘图界面是用RGBA模式还是颜色表模式,像系缓存是用单缓存还是双缓存,以及颜色位数、深度缓存和模板缓存所用的位数,还有其他一些属性信息。
(1)像素格式结构
每个OpenGL显示设备都支持一种指定的像素格式号。一般用一个名为PIXELFORMATDESCRIPTOR的结构来表示某个特殊的像素格式,这个结构包含26个属性信息。Win32定义的PIXELFORMATDESCRIPTOR如下所示:
typedefstructtagPIXELFORMATDESCRIPTOR
{
WORDnSize;
WORDnVersion;
DWORDdwFlags;
BYTEiPixelType;
BYTEcColorBits;
BYTEcRedBits;
BYTEcRedShift;
BYTEcGreenBits;
BYTEcGreenShift;
BYTEcBlueBits;
BYTEcBlueShift;
BYTEcAlphaBits;
BYTEcAlphaShift;
BYTEcAccumBits;
BYTEcAccumRedBits;
BYTEcAccumGreenBits;
BYTEcAccumBlueBits;
BYTEcAccumAlphaBits;
BYTEcDepthBits;
BYTEcStencilBits;
BYTEcAuxBuffers;
BYTEilayerType;
BYTEbReserved;
DWORDdwLayerMask;
DWORDdwVisibleMask;
DWORDdwDamageMask;
PIXELFORMATDESCRIPTOR,
*PPIXELFORMATDESCRIPTOR,
FAR*LPPIXELFORMATDESCRIPTOR;
(2)初始化PIXELFORMATDESCRIPTOR结构
PIXELFORMATDESCRIPTOR中每个变量值的具体含义和设置可以参
考有关资料,下面举出一个PIXELFORMATDESCRIPTOR初始化例子来简要
说明相关变量的意义。定义PIXELFORMATDESCRIPTOR结构的pfd如下:
PIXELFORMATDESCRIPTORpfd=
{
sizeof(PIXELFORMATDESCRIPTOR),//结构尺寸
l,//结构版本
PFD-DRAW-TO-WINDOWS|PFD-SUPPORT-OPENGL,//特性标志
PFD-TYPE-RGBA,//RGBA模式
24,//24位颜色
0,0,0,0,0,0,//不涉及这些属性
0,0,0,0,0,0,0,//没有alpha缓存和累积缓存
32,//32位深度缓存
0,0,//没有模板缓存和辅助缓存
PFD-MAIN-PLANE,//主层类型
0,//保留结构数
0,0,0,//不支持结构数
};
在这个结构里,前两个变量的含义十分明显。第三个变量dwFlags的值是PFD-DRAW-TO-WINDOWS|PFD-SUPPORT-OPENGL,表明应用程序使用OpenGL函数来绘制窗口,第四个表明当前采用RGBA颜色模式,第五个采用24位真彩色,即1.67千万种颜色,如果是256色系统则自动实现颜色抖动;因为没有使用alpha缓存和累积缓存,所以从变量cAlphaBits到cAccumAlphaBits都设置为0;深度缓存设置为32位,这个缓存能解决三维场景的消隐问题;变量cAuxBuffers设置为0,在WindowsNT下不支持辅助缓存;WindowsNT下针对OpenGL变量ilayerType只能设置为PFD-MAIN-PLANE,但其他平台也许支持PFD-OVERLAY-PLANE或PFD-UNDERLA
Y-PLANE;接下来bReserved变量只能设为0,而最后三个变量WindowsNT都不支持,故全设置成0。
(3)设置像素格式
当初始化PIXELFORMATDESCRIPTOR结构后,就要设置像素格式。下面几段从VC++2.0的MFC程序中摘出的代码就是设置像素格式的方式。代码如下:
CClientDCclientDC(this);
intpixelFormat=ChoosePixelFormat(clientDC.m-hDC,&pfd);
BOOLresult=SetPixelFormat(clientDC.m-hDC,pixelFormat,&p
fd);
第一行语句说明得到一个应用窗口客户区的设置描述表。
第二行调用ChoosePixelFormat()选择一个像素格式,并将像素格式索引号返回给pixelFormat变量;函数中第一个参数是选择像素格式的设置描述表的句柄,第二个参数是PIXELFORMATDESCRIPTOR结构的地址。如果调用失败则返回0;否则返回像素格式索引号。
第三行调用SetPixelFormat()设置像素格式,三个参数分别是设备描述表的句柄、像素格式索引号和PIXELFORMATDESCRIPTOR结构的地址。如果调用成功则返回TURE;否则返回FALSE。
3.创建图形操作描述表
正如前所述,必须创建图形操作描述表并启用它后,才能调用OpenGL函数在窗口内进行各种图形操作。一般说来,利用MFC中增补的管理图形操作描述表方法来编程比较方便。下面举一例:
intCopenglView::OnCreate(LPCREATESTRUCTlpCreateStruct
)
{
if(CView::OnCreate(lpCreateStruct)==-1)return-1;
//TODO:Addyourspecializedcreationcodehere
PIXELFORMATDESCRIPTORpfd=
{
sizeof(PIXELFORMATDESCRIPTIOR),
//structuresizel,
//structureversionnumber
PFD-DRAW-TO-WINDOWS|PFD-SUPPORT-OPENGL,//propertyflags
PFD-TYPE-RGBA,//RGBAmode
24,//24bitcolor
0,0,0,0,0,0,//notconcernedwiththese
0,0,0,0,0,0,0,//noalphaoraccumbuffer
32,//32bitdepthbuffer
0,0,//nostencilorauxbuffer
PFD-MAIN-PLANE,//mainlayertype
0,//reserved
0,0,0//unsupported
};
CClientDCclientDC(this);
intpixelFormat=ChoosePixelFormat(clientDC.m-hDC,&pfd);
BOOLresult=SetPixelFormat(clientDC.m-hDC,pixelFormat,&p
fd);
m-hRC=wglCreateContext(clientDC.m-hRC);
return0;
}
voidCOpenglView::onDraw(CDC*pDC)
{
COpenglDoc*pDoc=GetDocument();
ASSERT-VAILD(pDoc);
//TODO:adddrawcodefornativedatahere
wglMakeCurrent(pDC->m-hDC,m-hDC);
DrawMyOpenGL();
wglMakeCurrent(pDC->m-hDC,NULL);
}
voidCOpenglView::OnDestroy()
{
CView::OnDestroy();
//TODO:Addyourmessagehandlercodehere
wglDeleteContext(m-hRC);
}
微机UNIX直接视频图形程序设计有两种方法,一种是利用设备驱动程序(见参考文献1),另一种是针对IBM标准终端进行编程,本文介绍后者。
一、图形程序设计
1.检测视频适配器
视频显示器是由视频适配器硬件控制的,视频适配器决定了图形方式下显示图形的分辨率及可能的颜色[2]。利用系统调用ioctl中的CONS-CURRENT命令可以检测到当前的视频适配器,即:
ioctl(0,CONS-CURRENT,NULL)
返回-1时表示出错,即没有相应的视频适配器硬件,如果检测到VGA卡则返回值为VGA,如果检测到EGA卡则返回值为EGA,……。
2.初始化图形系统
初始化图形必须完成下列任务。
(1)获取当前的视频显示方式
ioctl的CONS-GET命令用来判断当前适配器的显示方式,即:
ioctl(0,CONS-GET,NULL)
它返回显示方式的值,这些值在包含文件vtkd.h中均有定义,如:SW-VAG640x480C为VGA适配器设置成640x480分辨率彩色图形模式。
(2)设置图形模式
直接将图形模式值放入ioctl中的命令项即可设置相应的图形模式,如ioctl(0,SW-VGA640x480C,NULL)
将VGA适配器设置成640x480分辨率的彩色图形模式。
(3)获取图形模式下视频缓冲区物理地址
利用ioctl的MAPCONS命令可以实现此功能,即:
char*scrnmem;
scrnmem=(char*)ioctl(0,MAPCONS,NULL)
所有实现基本图素的操作都将针对scrnmem进行,scrnmem就是EGA/VGA相应的四个位平面的重叠地址,有关EGA/VGA的结构可参阅[2]。
3.实现基本图素
DOS操作系统下,对EGA/VGA的各种视频I/O寄存器进行操作是很方便的,可以直接使用汇编语言in和out指令进行读写。然而,UNIX操作系统下,对物理硬件的访问都是由UNIX系统核心和设备驱动程序管理的,要访问EGA/VGA的各种I/O寄存器,必须获得对其访问的特权,为了实现这种功能要求,可以使用下列ioctl系统调用方式:
ioctl(0,VGA-IOPRIVL,1)获取VGA的各种I/O寄存器的访问特权
ioctl(0,EGA-IOPRIVL,1)获取EGA的各种I/O寄存器的访问特权
UNIX操作系统基本上是采用C语言编写的,只是在低层的系统内核方面才使用低级的汇编语言,遵循这一原则,对EGA/VGA的I/O寄存器的访问可以采用汇编语言,而实现图形系统的基本图素则采用C语言。
如果用户的UNIX系统中已有inb()和outb()函数(嵌入在/usr/include/sys/inline.h中),则可以直接使用它们完成对各种I/O寄存器的读写,否则,必须编写下列低级汇编语言例程:
/*向一端口输出一字节*/
/*从一端口输入一字节*/
voidoutb(intport,ucharvalue)
{
-asmpushedx
-asmmovedx,port
-asmmoval,value
-asmoutdx,al
-asmpopedx
}
ucharinb(intport)
{
-asmpushedx
-asmmovedx,port
-asminal,dx
-asmpopedx
}
基本图素一般包括:设置颜色,对调色板的操作,画点、线、弧、矩形、圆、椭圆、多边形、画扇形、饼图,任意图形填充,多边形填充,保存屏幕,恢复屏幕等,这些操作均可用C语言实现,细节问题可参阅[2]。
4.关闭图形系统
退出图形系统之前必须恢复EGA/VGA各I/O寄存器的值,并将显示模式恢复到进入图形模式之前的模式。采用下列ioctl调用实现:
ioctl(0,MODESWITCH|oldmode,NULL)
oldmode是进入图形方式之前获取的方式,UNIX系统中,获取的方式和设置的方式之间的关系为:
设置方式值=获取方式值|MODESWITCH
二、虚拟终端的使用
虚拟终端(VirtualTerminal,简称VT)加强了UNIX系统V/386的接口功能,它不仅允许单个用户开发一个图形应用软件,而且允许多用户、多道程序在同一个物理终端上运行,在开始一个用户的应用程序之前不必停止另一个应用程序,而且各个用户之间可以互相切换。
虚拟终端有两种操作方式[1],一种是自动操作方式(VT-AUTO),这是默认情况,比较简单,应用程序并不了解终端用户接受或放弃当前VT的请求,这意味着被切换掉的进程的任何输入输出都可能丢失。另一种方式是进程控制方式(VT-PROCESS),该方式支持应用程序与其它正在使用VT的进程之间同步,应用程序可以负责接受或放弃使用VT。
[1]中介绍了以进程方式控制VT的过程,并以设备驱动程序方式介绍了接受和放弃对VT控制的信号处理例程。本文给出针对IBM标准终端编制VT的程序和相应的信号处理例程。
/*设置虚拟终端*/
voidsetvirtualterm(void)
{
structvt-modevtmode;
signal(SIGUSR1,release-disp);//release-disp为放弃VT的信号处理例程
signal(SIGUSR2,acquire-disp);//acquire-disp为接受VT的信号处理例程
vtmode.mode=VT_PROCESS;//设置进程控制方式
vtmode.relsig=SIGUSR1;
vtmode.acqsig=SIGUSR2;
if(ioctl(0,VT-SETMODE,&vtmode)==-1)exit(1);//出错即终止此进程
}
/*放弃VT的信号处理例程*/
voidrelease-disp(void)
{
signal(SIGUSR1,release-disp);
保存整个图形屏幕于内部缓冲区videobuf中;
ioctl(0),MODESWITCH|oldmode,NULL);
//oldmode为进入图形模式之前的显示方式
ioctl(0,VT-RELDISP,VT-TRUE);
//VT-TRUE表明同意放弃VT,如果此项为0,则表示拒绝放弃VT.
}
/*接受VT的信号处理例程*/
voidacquire-disp(void)
{
signal(SIGUSR2,acquire-disp);
ioctl(0,newmode,NULL);//newmode为应用程序所处的图形模式
scrnmem=(char*)ioctl(0,MAPCONS,NULL);
//重新获取图形缓冲区的物理地址
从videobuf中恢复整个图形屏幕,并释放videobuf;
ioctl(0,VT-RELDISP,VT-ACKACQ);//VT-ACKACQ表明接受VT
}
在微机UNIX操作系统下,针对EGA/VGA进行直接视频程序设计,独立开发一个图形程序包,不仅小巧方便,而且可以重用以前在DOS下开发的图形应用程序。笔者在SCOUNIX系统下开发了一个小的低层图形软件包,许多以前的DOS图形应用程序都可以移植到UNIX系统下来。
另外,本文介绍的程序在使用前还应包含下列文件,即:
#include<stdio.h>
#include<sys/types.h>
#include<sys/console.h>
#include<sys/vtkd.h>
#include<termio.h>
#include<sys/signal.h>
分配空间时还应加上#include<malloc.h>