77范文网 - 专业文章范例文档资料分享平台

毕业论文(9)

来源:网络收集 时间:2019-07-30 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

本程序框架的应用程序包,这样就可以在此基础上进行程序设计。在参考许多数字 处理、图像处理软件的基础上,决定采用单文档的应用程序框架。【16】

? 创建工程:启动VC++6.0进入VC++的集成开发环境,新建一个工程,选择 MFC Appwizard选项,在应用程序类型中选择 singledocument(单文档)类型。 ? 设置编译环境:设置编译环境主要包括设置包含文件和设置库文件路径。 ? 加入OpenGL库:选择菜单Project→Setting,将弹出 ProjectSettings对话 框,在该对话框选择Link标签页,如图4-4所示。在该对话框中的

Object/Library Module文本框中加入opengl32.lib、glu32.lib、glaux.lib 三个函数库文件。在头文件中加入 gl/glu.h(OpenGL核心函数的头文件)和

gl/glut.h(使用函数的头文件),这样就可以调用openGL软件包了。 图4-4 加入OpenGL库函数 这样,我们就很容易的建立了一个在Windows环境下进行OpenGL编程开发的 框架,按快捷键F7进行编译,按快捷键F5执行就会弹出一个窗口,包含一个主菜

单、一个工具条和一个状态条等部件。如下图4-5所示: 西南交通大学本科毕业设计(论文) 第37页 图4-5 程序框架 4.2.2 设置OpenGL绘图环境 1)创建RC

在windows环境下建立OpenGL绘制窗口是通过建立设备描述表(DC)和绘制描 述表(RC)来实现的,而RC和DC是连接在一块的。因此,为了建立RC,先要建立 DC。用ChoosePixelFormat()选择系统中与pfd描述的像素格式最为匹配的返回; 本文现在消息响应函数OnCreate里调用InitializeOpenGL(m_pDC)函数,然后又通 过后者调用SetupPixelFormat()函数来设置DC像素格式完成绘图环境的设置工作; int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct) {

if (CView::OnCreate(lpCreateStruct) == -1) return -1;

m_pDC = new CClientDC(this);

InitializeOpenGL(m_pDC); //调用函数 ...

return 0;

} 西南交通大学本科毕业设计(论文) 第38页 BOOL CMyView::InitializeOpenGL(CDC* pDC) {

m_pDC = pDC;

SetupPixelFormat();//设置像素格式

m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());

::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);//选择像素格式 return TRUE; }

2)设置坐标变化方式

每次窗口创建或改变大小的时候,都要重新设置视口大小,因此我们在OnsizeO 中进行视口设置。而投影变换和视点一模型变换的初始设置也可以放在里面进行。 void CMyView::OnSize(UINT nType, int cx, int cy) {

CView::OnSize(nType, cx, cy); if (cy==0) // 防止被零除

{cy=1; }

glViewport(0,0,cx,cy);// 重置当前视口

glMatrixMode(GL_PROJECTION);// 选择投影矩阵 glLoadIdentity(); // 重置投影矩阵

gluPerspective(45.0f,(float)cx/(float)cy,0.1f,2000.0f);//设置透 视投影矩阵

glMatrixMode(GL_MODELVIEW);// 选择模型观察矩阵 glLoadIdentity(); // 重置观察模型矩阵 }

3)绘图显示

完成上面的设置以后我们就可以利用OpenGL进行绘图了。本文为了程序的简 约,先在OnDraw()里调用RenderScene()函数,然后在RenderScene()里调用所 有绘图显示函数。代码如下:

void CMyView::OnDraw(CDC* pDC) {

CMyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

RenderScene(); //调用绘图函数

} 西南交通大学本科毕业设计(论文) 第39页 4)程序结束,释放资源。

调用消息响应函数OnDestroy(),在函数里完成相关资源的释放。 void CMyView::OnDestroy() {

CView::OnDestroy(); ::wglMakeCurrent(0,0); ::wglDeleteContext( m_hRC); if (m_hPalette)

DeleteObject(m_hPalette); if ( m_pDC ) {

delete m_pDC; } ... }

最后按照参考书上的方法设置了全屏显示按钮,可以实现全屏显示,同时可以 进行屏幕工具栏的显示缩放。【16】 编译运行结果如图4-6所示:

图4-6 设置完成的机器人三维场景框架 西南交通大学本科毕业设计(论文) 第40页 4.3 机械手三维模型的建立 OpenGL中模型的建立一般有两种思路,一种通过一个是用3dsMax绘制出模型 并将其转换成特定格式的文件,然后导入到程序中;另一个是直接用OpenGL的函

数绘制出所需要的模型。导入的模型比较美观漂亮,但是实现起来技术难度比较大,

而OpenGL的函数绘制出的模型则比较粗糙,但是灵活性好,实现起来也比较容易。 4.3.1 导入机械手模型 利用openGL建立复杂物体的三维模型是一件比较麻烦和枯燥的事情,因为

OPenGL并没有提供三维模型的高级命令,它也是通过基本的几何图元一点、线及多 边形来建立三维立体模型的。而利用3dsMax建立复杂物体的模型则显得轻松的多。 可是,用3dsMax制作的动画没有交互性,无法实时控制,而这正是OpenGL的优势 所在。把这些模型转换成OpenGL程序,再对其进行控制是一种比较理想的方法。 所以,如果可以把OpenGL与3dsMax结合起来实现三维仿真则可以事半功倍。但是 由于时间和知识的限制,无法完成对3D模型的读取工作,所以查找了一些读取3D 模型文件的代码,利用这些代码将机械手模型转换成了OpenGL程序,将模型导入 进了OpenGL里。为了节约时间作者没有在3dsMax里建立机械手的模型,而是在比 较熟悉的Auto CAD里建立了机械手的模型,然后通过3dsMax软件模型文件导出成 接口程序可识别的*.ASE格式的文件,再通过接口程序导入进OpenGL里。导入前的 在3dsMax里的模型如图4-7所示: 图

4-7

3dsMax

西南交通大学本科毕业设计(论文) 第41页 导入后的机械手模型经过坐标变换、缩放、改变颜色并加入光照照亮后如下图 4-8所示:

图4-8 导入的机械手模型 4.3.2

在OpenGL中建立机械手的模型 虽然实现了模型的导入,但是只实现了整体导入,未能实现分块导入机械手的

模型,所以在OpenGL只实现了整体模型的控制,很显然满足不了机械手运动的要 求,所以导入的模型只能作为仿真场景的一部分做静态显示。为了继续进行后续工 作,作者直接在OpenGL中通过基本的几何图元一点、线及多边形建立了机械手的 三维立体模型。机械手模型主要由底座、腰部、关节、手臂这几个部分组成,由于 底座、腰部和关节都是圆柱型的,所以作者先利用glu库函数(gluCylinder和 gluDisk)【17】画出一个共用的圆柱,然后通过不同的缩放(glScalef)、转移 (glTranslatef)、旋转(glRotatef)变换绘制出了底座,腰部和关节的模型。这 里取绘制关节的函数作为例子介绍绘制过程,代码如下: void CMyView::joint() {

glPushMatrix();//模型入栈 GLUquadricObj *obj1;

obj1=gluNewQuadric();//创建一个描述当前绘图模式、定位、光照模式、 西南交通大学本科毕业设计(论文) 第42页 纹理模式和回调函数的不透明的状态变量

glTranslatef(0.0,0.0,-5.0);//向Z轴负方向即屏幕里移动5个像素的距 离

glPushMatrix();

gluCylinder(obj1,10.0,10.0,10.0,360.0,2);//绘制一个顶面半径、底面 半径和高度都为10的圆柱面 glPopMatrix();

glPushMatrix();

gluDisk(obj1,0.0,10.0,360,1);// 绘制一个半径为10的圆片堵住上述圆 柱面的底面

glPopMatrix(); glPushMatrix();

glTranslatef(0.0,0.0,10);//向Z轴正方向即屏幕外移动10个距离 gluDisk(obj1,0.0,10.0,360,1);//绘制一个半径为10的圆片堵住上述圆 柱面的顶面

glPopMatrix();

glPopMatrix();//模型出栈

}

绘制手臂也很简单,手臂其实在这里同样是通过对一个立方体进行不同的然后 通过不同的缩放(glScalef)、转移(glTranslatef)、旋转(glRotatef)变换来 完成绘制。OpenGL里也有对应画立方体的库函数,但是由于不太清楚怎么对用库函 数绘制的模型进行纹理贴图,所以选用了一种比较熟悉和简单的方式来绘制,就是 通过6个面来组合成一个立方体。对每个面都可以进行不同的纹理贴图。在后面的 仿真场景建立过程中同样利用这个四方体也完成了实验室房间、木质方桌、大理石 长桌、凳子和储物箱的绘制。绘制立方体的代码如下: void CMyView::shoubi() {

glPushMatrix();

glColor4f(1.0f,1.0f,1.0f,1.0f);//定义面的颜色为白色 glBegin(GL_QUADS);//开始绘制 // 前面

glTexCoord2f(0.0f, 0.0f); glVertex3f(-100.0f, 0.0f, -100.0f); // 纹理和四边形的左下

glTexCoord2f(1.0f, 0.0f); glVertex3f( 100.0f, 0.0f, -100.0f); 西南交通大学本科毕业设计(论文) 第43页 // 纹理和四边形的右下

glTexCoord2f(1.0f, 1.0f); glVertex3f(100.0f, 100.0f, -100.0f); // 纹理和四边形的右上

glTexCoord2f(0.0f, 1.0f); glVertex3f(-100.0f, 100.0f, -100.0f); // 纹理和四边形的左上 glEnd();

glBegin(GL_QUADS);

// 后面

glTexCoord2f(1.0f, 0.0f); glVertex3f(-100.0f, 0.0f, 100.0f); // 纹理和四边形的右下

glTexCoord2f(1.0f, 1.0f); glVertex3f(-100.0f, 100.0f, 100.0f); // 纹理和四边形的右上

glTexCoord2f(0.0f, 1.0f); glVertex3f( 100.0f, 100.0f, 100.0f); // 纹理和四边形的左上

glTexCoord2f(0.0f, 0.0f); glVertex3f( 100.0f, 0.0f,100.0f); // 纹理和四边形的左下 glEnd(); ...

glPopMatrix(); }

绘制完机械手的各个部件以后就可以通过缩放(glScalef)、转移

(glTranslatef)、旋转(glRotatef)变换来完成整个机械手模型的绘制。代码如 下:

void CMyView::manipulator() {

glPushMatrix();

glTranslatef(0.0,-80.0,-20.0);//分别沿Y和X轴负方向移动80和20 //glRotatef(0.0,1.0,0.0,0.0);

glRotatef(-hand[i].rot1,0.0,1.0,0.0);//绕Y轴旋转-hand[i].rot1(第 一个关节角θ1第i时刻的值) glPushMatrix();

glTranslatef(0.0,-15.0,0.0);

glRotatef(-90,1.0,0.0,0.0);//沿X轴逆时针旋转90°

glPushMatrix(); 西南交通大学本科毕业设计(论文) 第44页 glTranslatef(0.0,0.0,20.0); glColor3f(1.0,0.0,0.0);//设置为红色

glScalef(1.0,1.0,5.0);//沿新的Z轴方向扩大5倍 joint();//绘制腰部 glPopMatrix();

glTranslatef(0.0,0.0,-5.0);

glScalef(3.0,3.0,0.5);//沿新的Y和X轴扩大3倍,新的Z轴方向缩小 0.5倍

glColor3f(0.0,1.0,0.0);//设置为绿色 joint();//绘制底座 glPopMatrix();

...//同样的方法绘制关节和两个手臂,这里不再一一叙述

}

在RenderScene()里调用manipulator(),编译运行后的结果如图4-9所示:

图4-9 OpenGL中绘制的机械手模型 4.4

建立仿真场景 场景中模型的绘制和上节机械手模型的绘制很类似,所以在这里不再做介绍, 西南交通大学本科毕业设计(论文) 第45页 这一节主要介绍纹理贴图的实现和设置光照。 4.4.1 纹理贴图的实现 OpenGL体系内有一块纹理内存,在有硬件加速的情况下,可能是位于显卡的

VRAM里,否则会是OpenGL库管理的一块内存。在这个纹理内存里图片是以特定的 内部格式保存的,有的显卡还支持压缩纹理技术,所以将纹理像素从应用程序内存 传到纹理内存需要进行格式转换。这在OpenGL中是通过分别描述像素在应用程序 内存和纹理内存的格式来完成的,真正转换工作OpenGL会在内部完成。定义纹理 的命令是

glTexImage2/1D(GL_TEX_IMAGE_2/1D,level,components,width,height,border,f ormat,type,*pixels );OpenGL术语称应用程序内存读出像素的过程为解码 (UNPACK),而向纹理内存写像素的过程为编码(PACK)。用

glPixelStore*(GL_[UN]PACK_*,参数值);命令设定编码[解码]格式 。对于贴纹理 过程我们只需关心解码过程。如今的显卡通常都有比较大的显存,其中有一部份是 专门的纹理存储区,有的卡还可以将最多64M系统内存映射为纹理内存,所以我们 有可能把经常要用的纹理就保留在纹理内存里以提高程序性能。OpenGL从1.2开始

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库毕业论文(9)在线全文阅读。

毕业论文(9).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/jiaoyu/666516.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: