OpenGL图像变换三篇

2024-09-11

OpenGL图像变换 篇1

关键词:OpenGL,SAR,双缓存,VxWorks操作系统

0引言

Vx Works操作系统是一种嵌入式操作系统,因其在实际操作中,具有良好的性价比,操作程序简洁实用,运行扎实可靠被广泛应用在通信、军事、航空、航天等高精尖技术以及实时性要求极高的领域中[1]。Vx Works操作系统在图形界面的通用开发方式是采用风河公司的图形开发软件Wind ML,但该软件在具体实操时,不能有效利用图形界面实现操作效率的提升,同时利用该软件处理的图像界面显示,效果单一模糊,最大的短板是该软件在面临诸如图像的动画、反走样等问题时无法提供解决渠道[2]。因此,考虑选择系统显卡自带的Open GL三维图形软件包,该软件最大的特点是通过建立函数关系进行操作,函数的设立、建构都依照实用简单的模型, 利用Open GL提供的函数功能,只需建构、设置一整套自己需要、简洁清晰的渲染函数就能完成图形选取、设计、规划,这样直接通过操作简单函数来进行图形制作, 针对性 、时效性强 ,所设计的 图形更具 直观性 ,同时Open GL可以很好地解决诸如图形的动画、反走样等显示效果方面出现的难题[3,4]。

Open GL是SGI公司开发的具有广泛运用性的一种软件接口,它的最大特点是可以移植,并且具备独立性, 不受窗口操作系统和硬件环境的制约,是一种用于实时3D图形的标准范例。Open GL的图像显示是基于硬件 (通常是显卡)实现的,在Open GL硬件运转情况下,调动Open GL API传送给硬件驱动程序,然后与图形显示硬件直接交互,如图1所示。由于软件技术的深度开发,Open GL在3D图形加速卡方面的发展日益加快,使得图形处理更为简洁、实用、高效[5]。

1软件设计

Open GL提供gl Draw Pixels函数绘制像素贴图。在操作环节它利用gl Raster Pos定义当前光栅位置的左下角,然后以gl Pixel Store操控像素贴图的格式。在雷达图像中,像素格式通常为灰度图,含256级亮度,每个字节对应一个像素的信息。在gl Raster Pos函数设置好当前光栅位置后,随即可利用gl Draw Pixels函数将图像从内存复制到帧缓冲区内。

Open GL支持双缓存技术,在显示前台缓存图像的同时,后台缓存绘制第二幅图像。当后台绘制完成后, 后台缓存中的图像就显示出来,此时原来的前台缓存开始绘制第3幅图像,如此循环往复,使屏幕上的画面看起来是连续的。

另外,还要考虑融合技术。这是一种最为基本的图像处理技术,应用面广泛,利用这种技术可以显示飞参等信息。在图像处理过程中,融合的方式多种多样,最主要的方式是使用Alpha通道。在程序中,使用Alpha值可以直接完成字体位图与图像信息的融合透明处理[6]。

1.1图像绘制

绘制像素贴图Open GL函数及其参数如下: (1)描述位图数据的存储格式。

这里要解决好如下两个问题:如何使用gl Read Pixels函数保存像素;如何为gl Draw Pixels函数读取像素。在程序中主要是利用该函数设置从内存中读取像素的格式来解决上述问题。

Void gl Pixel Storei ( Glenum pname , Glint param ) pname param

其中pname为要设置的参数; param是参数值。

控制从内存中读取像素的pname参数取值为:

GL_UNPACK_SWAP_BYTES

GL_UNPACK_LSB_FIRST

GL_UNPACK_ROW_LENGTH

GL_UNPACK_SKIP_ROWS

GL_UNPACK_SKIP_PIXEL

GL_UNPACK_ALIGMENT

程序参数取GL_UNPACK_ALIGMENT值为1,表示图像上每一行扫描的对齐方式是按照1个字节进行扫描对齐的。

(2)设置当前光栅位置,确定图像的起始位置

Void gl Raster Pos2i(GLint x,GLint y)

其中,x表示图像起始左下角的水平坐标;y表示图像起始左下角的垂直坐标。x,y的数据类型也可以是浮点数 ,相应的函 数名称是gl Raster Pos2f(GLfloat x, GLfloat y)。

(3)从内存将像素数据复制到帧缓冲区光栅位置

Void gl Draw Pixels(GLsizei width,GLsizei height, GLenum format,GLenum type,const GLvoid* pixels)

其中:width表示像素计的图像宽度;height表示像素计的图像高度;format表示绘制的像素的颜色空间; type是指绘制的像素类型;pixels是图像的像素数据的指针。雷达图像是灰度级数据,因此设置type参数为GL_UNSIGNED_BYTE,format参数设为GL_LUMI-NANCE。

1.2图像平滑滚动的实现

Open GL支持双缓冲系统,但在实际中Open GL函数不会用来交换前台缓冲区和后台缓冲区。但是令人欣慰的是,每个Open GL支持的窗口系统都可以通过设置一个函数调用来完成前后缓冲区之间的交换。在Win-dows中,函数是Swap Buffer。在程序中,函数是glx Swap-Buffer。

Open GL用双缓存技术来完成动画制作。程序默认帧存为两个视频缓存,在任意时刻,两者中只有一个内容能被显示出来。运行原理是,当前可见视频缓存称为前台视频缓存,不可见的(正在画)的视频缓存称为后台视频缓存。当后台视频缓存中的内容被要求显示时, Open GL就将它拷贝至前台视频缓存。在操作中显示硬件通过读取可见视频缓存中的内容,把相关结果显示在屏幕上。Open GL在双缓存模式下,位平面被默认切分为前台和后台位平面。通过绘制函数操作的图像首先被写向后台位平面,这就要求,在描画物体之前,首先必须把帧存设置成正确的组态,当后台出现完整的画之后,就调用glx Swap Buffer函数 ,使其称为 可见视频 缓存[7]。 glx Swap Buffer函数的工作过程如图2所示。

1.3生成位图字符

Open GL直接用于处理单色位图。这种储存形式单一、简洁,如果存储位为1则用指定的颜色填充该位,如果存储位为0,则用底色填充该位。如果按每行8位扫描,则按以下数组表示的位所生成的位图是字母B,如图3所示。

以同样的 方法 ,可以表示A~Z的字母 ,0~9的数字。要输出位图,需要调用gl Bitmap函数把位图按指定的位置显示在屏幕上。gl Bitmap原型为:

Void gl Bitmap(GLsizei width,GLsizei height,GL-float xorig,GLfloat yorig,GLfloat xmove,GLfloat ymove, const GLubyte* bitmap)

其中,width指定位图的宽,height指定位图的高,两者均以像素为单位;(xorig,yorig)为位图原点的坐标; (xmove,ymove)为位图基于当前光栅位置的偏移量;bit-map为存储位图的地址。

1.4融合处理

Open GL融合技术可以把源颜色与目的颜色进行某种方式的融合,通过融合组合成为目标颜色,从而生产出透明或半透明的特殊效果。颜色的比例融合通过Alpha进行操作,即RGBA颜色模型中的A。融合操作涉及两个因子,一个是源因子,另一个是目的因子。在进行融合计算之前,要完成两个因子的融合,完成此功能的函数是gl Blend Func,原型为:

void gl Blend Func(GLenum sfactor,GLenum dfactor)

参数sfactor说明怎样计算源因子,参数dfactor说明怎样计算目标因子。

设源融合 因子为 (Sr,Sg,Sb,Sa),目的因子 为 (Dr,Dg, Db,Da),则融合后的颜色为:(RsSr+ RdDr,GsSg+ GdDg,BsSb+ BdDb,AsSa+ AdDa),颜色的各个分量最后自动进行归一化处理。

融合作为一种特殊的功能,必须进行启动和关闭声明:

gl Enable ( GL_BLEND );

gl Disable ( GL_BLEND );

2测试结果

显卡输出的雷达图像视频经视频采集卡接收处理后,实现图像的正常显示,如图4所示。

在显卡显示噪声的同时,会叠加载机信息。

3结语

OpenGL图像变换 篇2

CPU、GPU效率有关,可以改进OpenGL渲染流程,根据GPU和CPU实际情况,优化分配绘图、渲染任务,不仅能够优化图像处理速度,还可以实现图像渲染加速。以下本篇针对OpenGL图像渲染加速方法,进行实验研究。

关键词:图像渲染 OpenGL 渲染速度

1 OpenGL简介

OpenGL是一个跨平台的图形库,可在Windows、Unix、Mac等平台上运行。本书主要介绍怎样在Windows平台上建立OpenGL程序,并以Visual C++ 6.0编程环境为例来说明整个编程环境的建立和设置[1]。OpenGL指令模式,也就是在C/S(CIient/Server,客户/服务器)模型之中,通常可以根据用户程序中(客户)发出的命令,将其提交给相应内核程序中的(服务器),内核服务器再对收到的不同指令进行相应的解释,并在进行初步处理之后,将其交给操作系统服务管理,然后再转交给硬件进行计算加速。

2 OpenGL图像渲染流程

对于实际中的OpenGL指令,主要是集封装在库以及共享程序集之中的,可以当应用程序发出的OpenGL命令,以此来调用库处理文件。然后,可以传递服务到内核处理。其工作流程如下图所示:

[应用程序][包含OpenGL指令][OpenGL指令集(Windows上以DLL形式存在)][OpenGL内核服务][操作系统服务][显卡驱动][显示卡][显示器]

图1 OpenGL工作流程

应用程序OpenGL内核服务显示器显示卡显卡驱动操作系统服务包含OpenGL指令OpenGL指令集(Windows上以DLL形式存在)OpenGL图像渲染中,具有超强图形绘制的能力,主要包括绘制物体指令、启动光照指令、管理位图指令、图像纹理映射指令、动画指令,还与图像实现交互,发挥实际功能[2]。对于OpenGL渲染中,首先可以将物体转化成可以描述的物体,使其形成具有集合性质的顶点(Vertex),以及形成可以描述图像性质的像素(Pixel),并能够在执行一系列的操作之后,最终把这些数据转化成相应的像素数据。

3 分析研究OpenGL图像渲染加速试验

3.1 试验环境

可以在windows操作系统之下,对OpenGL应用程序指令,主要就是被封装在OpenGL32.dll库以及Glu32.dl动态链接库中。其中,Glut库作为OpenGL图像渲染过程中的实用工具包,是一个可以独立于子窗口的系统工具包,在OpenGL可以发挥隐藏特性,能够以此来隐藏不同窗口系统的API复杂性。实际应用中,Glu只封装基础API窗口,只是用于OpenGL的教学演示。在应用中,可以在文件首部中添加头文件:

# include “ gl \ gl.h”

# include “gl \ glu.h”

然后,可以打开菜单Project\Settings选型,随后可以在弹出的对话框中,选择Link 的标签,并在Object\Library Modules 栏,可以增加OpenGL32.lib 及glu32.lib 两个库文件。

3.2 像素格式设置

对于OpenGL图像渲染过程中,对其进行绘图操作指示, OpenGL可以将数据转化为像素,使其可以写入帧中进行缓存。因此在OpenGL图像渲染中,OpenGL只需要知道像素格式,就可以在初始化OpenGL时,根据PIXELFORMATDESCRIPTOR函数,设置像素的属性格式。

3.3 设置渲染描述表

对于OpenGL渲染加速中,应用描述表来表示输出同Windows设备的联系机制,可以把OpenGL图像渲染信息存入描述表,在Windows系统中,更新OpenGL中一个窗口图形的状态[3]。利用“MFC ClassWizard”,使CMFCOpenGLExplView类响应WM_CREATE、WM_SIZE、WM_ERASEBKGND、WM_DESTROY、WM_LBUTTONDOWN、WM_RBUTTONDOWN、和WM_TIMER這7个消息,得到相应的7个消息响应函数。

3.4 绘制图像

在OnDraw()函数中调用成员函数RenderScene()来绘制场景,该函数体其实就是ConsoleExpl工程中display()的函数体。

void CMFCOpenGLExplView::OnDraw(CDC* pDC)

{CMFCOpenGLExplDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

RenderScene();}

void CMFCOpenGLExplView::RenderScene()

{gl Clear ( GL_COLOR_ BUFFER_BIT | GL_ DEPTH_BUFFER_BIT );

glPushMatrix();//保存模型视图矩阵

glRotatef(m_rotAngle, 0.0, 0.0, 1.0);

glBegin(GL_POLYGON);

glColor3f(1.0, 0.0,0.0);

glVertex2f(0.0, -25.0);

glColor3f(0.0, 1.0, 0.0);

glVertex2f(25.0, -12.5);

glColor3f(0.0, 0.0, 1.0);

glVertex2f(25.0, 12.5);

glColor3f(1.0, 1.0, 0.0);

glVertex2f(0, 25.0);

glColor3f(1.0, 0.0, 1.0);

glVertex2f(-25.0, 12.5);

glColor3f(0.0, 1.0, 1.0);

glVertex2f(-25.0, -12.5);

glEnd();

glPopMatrix();//恢复模型视图矩阵

SwapBuffers(wglGetCurrentDC());//交换缓冲区}

绘制出结果,并且基于整个处理过程中,都可以确保在计算机的后台模式下完成,并且只需要程序员开发应用程序部分,基本上后续工作则不需要程序员参与,对于硬件的管理工作也可以交由计算机完成,具有实际应用价值。

4 结论

综上所述,实验研究证实,在基于OpenGL图像渲染基础上,应用OpenGL,有效实现图像渲染加速,优化图像渲染流程,值得在实际中应用推广。

参考文献:

[1]乔少杰,王有为.基于OpenGL的快速图像渲染方法[J].计算机应用研究,2008,5(5):1589-1595.

[2]苏国中.OpenGL模拟摄影测量方法研究[J].中国图像图形学报,2006(04).

[3]向世明.OpenGL 编程与实例[M].北京:电子工业出版社,1999:22-82.

OpenGL图像变换 篇3

(二)OpenGL坐标变

换之平移及旋转

世界坐标系:

在OpenGL中,世界坐标系是以屏幕中心为原点(0, 0, 0),且是始终不变的。你面对屏幕,你的右边是x正轴,上面是y正轴,屏幕指向你的为z正轴。长度单位这样来定:窗口范围按此单位恰好是(-1,-1)到(1,1),即屏幕左下角坐标为(-1,-1),右上角坐标为(1,1)。

当前绘图坐标系:

是绘制物体时的坐标系。程序刚初始化时,世界坐标系和当前绘图坐标系是重合的。当用glTranslatef(),glScalef(), glRotatef()等对当前绘图坐标系进行平移、伸缩、旋转变换之后,世界坐标系和当前绘图坐标系不再重合。注意,这里的平移旋转是将当前绘图坐标系看做一个整体在世界坐标系中进行旋转平移。然后,改变以后,再用glVertex3f()等绘图函数绘图时,都是在当前绘图坐标系进行绘图,所有的函数参数也都是相对当前绘图坐标系来讲的。其中四种坐标经常要在程序中用到:世界坐标,物体坐标,设备坐标和眼坐标。

1、世界坐标是OpenGL中用来描述场景的坐标,Z+轴垂直屏幕向外,X+从左到右,Y+轴从下到上,是右手笛卡尔坐标系统。我们用这个坐标系来描述物体及光源的位置。

将物体放到场景中也就是将物体平移到特定位置、旋转一定角度,这些操作就是坐标变换。OpenGL中提供了glTranslate*/glRotate*/glScale*三条坐标变换命令,利用OpenGL的矩阵运算命令,则可以实现任意复杂的坐标变换。

OpenGL中有一个坐标变换矩阵栈(ModelView),栈顶就是当前坐标变换矩阵,进入OpenGL管道的每个坐标(齐次坐标)都会先乘上这个矩阵,结果才是对应点在场景中的世界坐标。OpenGL中的坐标变换都是通过矩阵运算完成的,与图形学课本的描述完全一致。要注意的是变换中的矩阵乘法是左乘,而矩阵乘法与算术乘法不同,不符合交换律(万一不明白去看矩阵代数书好了)。

glTranslate*(x,y,z):平移,参数为各轴向的移动量。

glRotate(d,x,y,z):旋转,第一个参数为转动的度数,后三个参数表明是否绕该轴旋转。通常x,y,z中只有一个为1,其余为0,用连续几条旋转命令完成复杂旋转。由于矩阵运算的左乘特点,旋转命令的顺序与旋转动作的顺序正好相反。

2、物体坐标是以物体某一点为原点而建立的“世界坐标”,该坐标系仅对该物体适用,用来简化对物体各部分坐标的描述。物体放到场景中时,各部分经历的坐标变换相同,相对位置不变,所以可视为一个整体,与人类的思维习惯一致。

3、眼坐标是以视点为原点,以视线的方向为Z+轴正方向的坐标系中的方向。OpenGL管道会将世界坐标先变换到眼坐标,然后进行裁剪,只有在视线范围(视见体)之内的场景才会进入下一阶段的计算。同样的,有投影变换矩阵栈(Projection),栈顶矩阵就是当前投影变换矩阵,负责将场景各坐标变换到眼坐标,由所得到的结果是裁剪后的场景部分,称为裁剪坐标。前面提到过的视见体设定其实就是在建立该矩阵。

4、设备坐标:OpenGL 的重要功能之一就是将三维的世界坐标经过变换、投影等计算,最终算出它在显示设备上对应的位置,这个位置就称为设备坐标。在屏幕、打印机等设备上的坐标是二维坐标。值得一提的是,OpenGL可以只使用设备的一部分进行绘制,这个部分称为视区或视口(viewport)。投影得到的是视区内的坐标(投影坐标),从投影坐标到设备坐标的计算过程就是设备变换了。

对应代码:

package com.example.hejunlin.openglcoordinate;

import android.opengl.GLSurfaceView;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

private GLSurfaceView mSurfaceView;

@Override

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savelors);

colorsBuffer.position(0);

}

public void draw(GL10 gl){

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexsBuffer);

gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorsBuffer);

gl.glLineWidth(9);

gl.glDrawArrays(GL10.GL_LINES, 0, vertexs.length / 3);

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

} }

void glTranslatef(GLdouble x,GLdouble y,GLdouble z);参数说明:

x,y,z:分别指定沿x,y,z轴方向的平移分量。

重点就是沿着x,y,z轴移动。

注意在glTranslatef(x, y, z)中,当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。

上一篇:分析时间下一篇:土地配置