刘建新,明 亮,张 霆,赵立营
(南京电子技术研究所, 江苏 南京 210039)
雷达显控软件为提供了操作员与雷达系统的人机交互接口[1],其用户体验直接影响战术操作与战场决策,流畅的人机交互界面决胜战场的基本保障[2-3]。随着雷达技术的不断发展,雷达探测能力的不断提升[4-5],雷达航迹容量与日俱增,传统雷达显控软件的航迹显示方法已不能满足当前雷达对显示效率的要求。
目前大部分雷达显控软件在进行航迹显示时,采用的是逐点绘制的方法,这种主要存在三个问题:一是绘制航迹时需要在一个绘制周期内遍历所有航迹点,在目标容量巨大的情况下完成该工作需要耗费较大的中央处理单元(CPU)资源;二是逐点将内存中的数据传到图形处理器(GPU)[6]造成总线资源的浪费;三是每次只绘制一个航迹点,无法充分利用GPU高并行的处理能力,导致GPU资源浪费。
针对上述问题,本文设计了一种高效的雷达航迹显示方法,该方法利用双缓存技术实现航迹数据的组织,降低CPU的计算压力;利用OpenGL着色器技术实现航迹的绘制,充分发挥显卡的高并行处理能力[7-8],从而提升雷达显控软件的显示效率。
OpenGL提供了一组操控显卡硬件的API,为了提高绘图效率,OpenGL借鉴了工厂流水线的概念,称为管线[9]。着色器是运行在GPU上的代码段,通过着色器可实现对显卡进行编程。不同的着色器对应管线的不同阶段。图1为OpenGL绘图管线示意图。
图1 OpenGL绘图管线示意图Fig.1 OpenGL painting pipeline schematic map
其中统一值为着色器各阶段的公用信息。顶点着色器用于处理所要绘制顶点的位置信息,可完成顶点位置的投影变换工作,是OpenGL绘图所必需的着色器。几何着色器[10]可一次性对整个图元(三角形、线、点等)进行处理,可以改变一个图元的类型,几何着色器在OpenGL管线中是可有可无的。片段着色器的作用是确定每一个细小片段颜色,是OpenGL绘图所必需的。GPU中存在很多可编程单元,每个单元都可以执行一段着色器程序,OpenGL管线中的着色器都是独立工作的,因此利用OpenGL着色器绘制航迹具有高并行处理的特点,从而极大提高显示效率。
本文采用双缓存技术组织航迹数据,以降低CPU的处理压力,提升显示效率。双缓存包括后台缓存和前台缓存。后台缓存用于组织航迹数据,每次组织部分航迹数据,组织全部数据通过多次完成,以减少数据组织所带来的CPU压力。前台缓存是指已经组织好的数据,用于界面显示,以保障界面显示流畅。每个绘制周期内数据组织流程如图2所示。
图2 基于双缓存的数据组织流程图Fig.2 Data organization flowchat based on double buffers
1) 判断是否完成所有航迹数据组织工作,若是则翻转前后台缓存,保证前台缓存的数据总是完整有效的,同时为下一次后台缓存组织数据做准备。
2) 进入循环组织数据,遍历每一批航迹的所有历史点进行数据组织,直至完成UPDATE_TRK_NUM批航迹。
3) 每个绘制周期最多组织UPDATE_TRK_NUM批航迹数据,而不是所有目标数,可降低CPU耗时;组织数据只在后台缓存上进行,在完成所有航迹数据组织完成之前保证前台缓存数据不变。
4) 一次性将所有前台缓存数据传送到GPU,完成CPU上的数据组织工作,另外CPU与GPU是异步的,因此GPU上绘制所耗费的时间不影响显示效率。
GPU接收到全部前台缓存数据后,开始对数据进行并行处理,处理过程包括顶点着色器和片段着色器。
(1) 顶点着色器代码如下:
#version 330
uniform highp mat4 matrix;
attribute highp vec4 vertexpos;
attribute highp vec4 vertexcolor;
varying mediump vec4 color;
void main(void)
{
vec4 vertex;
vertex = vec4(0.0,0.0,0.0,1.0);
vertex.x = vertexpos.x;
vertex.y = vertexpos.y;
gl_Position = matrix * vertex;
color = vertexcolor;
}
片段着色器代码如下:
#version 330
varying mediump vec4 color;
void main(void)
{
gl_FragColor = color;
};
(2) 基于着色器的航迹绘制代码如下:
_pShardeProgram->setUniformValue(_UniMatAttr, pmvMatrix);
_pShardeProgram->enableAttributeArray(_VerPosAttr);
_pShardeProgram->enableAttributeArray(_VerColorAttr);
_pShardeProgram->setAttributeArray(_VerColorAttr, pVertex->_pColor, 4);
_pShardeProgram->setAttributeArray(_VerPosAttr, pVertex->_pVertex, 2);
glDrawArrays(GL_POINTS, 0, pVertex->_unVertexNum);
_pShardeProgram->disableAttributeArray(_VerColorAttr);
_pShardeProgram->disableAttributeArray(_VerPosAttr);
表1给出了不同目标数量情况下本文方法与传统方法航迹显示帧率(每秒刷新次数)对比结果,结果如下。
表1 航迹显示帧率实验结果Tab.1 Experimental results of track display frame rate
从上表结果可以看出,本文方法在航迹显示效率上相比于传统方法有了较大提升,大大改善了用户体验。
本文提供一种基于OpenGL着色器和双缓存的雷达航迹高效显示方法,该方法主要具有三方面优势:第一利用双缓存每次组织部分数据的优势,降低CPU的消耗;第二将组织好的数据一次性传入GPU,减少总线传输消耗;第三充分利用GPU高并行特性批量绘制航迹数据,提高显示效率。本方法已应用与功能实践,取得了良好的效果,下一步多线程显示方面进行更深入的研究和探讨。