搜档网
当前位置:搜档网 › 基于OpenGL的3D旋转魔方的实现

基于OpenGL的3D旋转魔方的实现

基于OpenGL的3D旋转魔方的实现
基于OpenGL的3D旋转魔方的实现

华中科技大学电子科学与技术系

课程设计报告

( 2011-- 2012年度第2 学期)

名称:软件课程设计

题目:基于OpenGL的3D旋转魔方实现

院系:XXXXXX

班级:XXXXX

学号:U201014185

学生姓名:X X X

指导教师:X X X

设计周数:XXXX

成绩:

日期:2012 年5月24日

目录

1.课程设计介绍 (1)

1.1.内容 (1)

1.2.目的 (1)

1.3.取得的成果 (1)

2.程序分析 (2)

2.1. 程序原理 (2)

2.1. 程序流程 (3)

2.3. 数据结构 (8)

2.4. 重要函数用法分析 (8)

3.结果演示与程序分析 (9)

3.1. 成果演示 (9)

3.2. 程序分析 (11)

4.编程中遇到的问题 (12)

5.课程设计小结 (13)

参考文献 (14)

基于OpenGL的3D旋转魔方实现

1.课程设计介绍

1.1目的

当今计算机技术流行,引领了各行各业。而程序是计算机的灵魂,因此编程能力对当今的学生而言至关重要。虽然我们在前期已经学习了C语言,但是还只对程序有一些简单的认识,说实话,是很浅显的认识。通过本软件课程设计的学习,可以从整体上对软件工程和项目有全面的认识。通过此次课程设计,可以锻炼编程能力,激发对编程的兴趣,同时也能培养良好的编程习惯。这对于个人今后的学习,今后的工作乃至今后的生活都会产生重要的影响。对于国家而言,极大的推动了计算机普及教育,提高了大学生的计算机使用水平,具有重大的意义。

1.2内容

(1)通过此次项目掌握软件开发模式,模块化结构分析以及程序设计流程

(2)学会使用VC++6.0进行编程

(3)掌握有关程序设计的思想,数据结构的知识,掌握C语言算法,掌握OpenGL 编程知识如贴图与键盘控制

(4)掌握win32编程知识,了解windows程序内部运行机制

(5)初步培养需求分析、软件测试、调试的能力

(6)在2X2魔方的基础上,尝试编写3X3的魔方,并实现其旋转

1.3取得的成果

在理解Magic2D例子程序的基础上,借助了Win32平台进行了一系列调试和学习。在此次项目中,学习了Visual C++6.0软件开发环境,熟练掌握了Win32 Application开发流程。同时也学习了OpenGL的基本知识,掌握了一些OpenGL的重要技术与重要函数的使用,编写了一些简单的OpenGL程序。参考Magic2D例子流程,我对原程序进行了比较大的修改,并换上了自己的图片,实现了一个立方体贴六张不同的图片,并编写出了自己的2X2魔方程序。根据相似度分析,成功的编写出了3X3旋转魔方,并自己设计了算法,实现了各个层面的转动,转动效果很完美。

同时,为了增加程序的娱乐效果,我加入了歌曲最炫民族风,虽然很简单,不过感觉非常实用且有趣。

2.程序分析

2.1 程序原理

(1)OpenGL

OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植;OpenGL可以与Visual C++紧密接口,便于实现机械手的有关计算和图形算法,可保证算法的正确性和可靠性;

OpenGL使用简便,效率高。

本设计是在Visual C++6.0开发环境下,使用OpenGL(Open Graphics Library)函数库,绘制魔方并实现魔方的绘制、随机旋转、贴图以及键盘控制等功能。采用基本图形的绘图函数及定位函数,添加相应纹理来实现魔方模型的绘制。通过读取载入BMP文件,应用纹理贴图技术来完成对魔方旋转面的处理。

(2)模型的旋转

首先对立方体进行建模。一个立方体由8个点组成,8个点组成6个面片,对立方体的几何操作本质上就是对这6个平面的操作(绘制、纹理、旋转和平移等)。点的索引号确定后,每个面片也就确定了,如{0,1,2,3}四个点构成Z向正投影面。

立方体在空间的旋转,归根到底是其顶点的旋转,如空间点(x, y, z)绕Z轴旋转a 对应的旋转矩阵:

cosa sina

-sina cosa

一个立方体pCube绕Z轴旋转a后对应的坐标变化为:

for( int i=0;i<8;i++)

{

float x,y;

x= pCube->CubePoint[i].p[0];

y= pCube->CubePoint[i].p[1];

pCube->CubePoint[i].p[0] = x*cosa - y*sina;

pCube->CubePoint[i].p[1] = x*sina + y*cosa;

}

其它轴的旋转类似。由于魔方体层面的旋转是90°,在某个层面内一个子立方体Ci会被另外一个Cj完全替换,因此旋转后必须同步更新魔方体Cube各层面内包含的子立方的索引号。为了简化算法,只需查找旋转后Cube[i]在Static_Cube中对应的小立方编号j与i的位置匹配。

2.2 程序的流程

通过分析,整个程序大致可以分为6个子功能模块

(1)Win32应用程序框架

WinMain主函数是所有Win32程序的入口点。在WinMain函数里实现Window是窗体的建立和消息循环,在消息循环中实现键盘、鼠标输入事件处理响应,具体内容可参考VC程序参考手册。在本课程程序中,不仅要创建Window窗体,而且构建OpenGL设备绘图环境。

Window窗体创建步骤:

●窗体类注册:RegisterClass

●设置显示分辨率:ChangeDisplaySettings

●设置窗体大小:AdjustWindowRectEx

●创建窗体:CreateWindowEx

OpenGL绘图环境搭建:

●获取设备绘图环境(DC,DeviceContext):hDC=GetDC(hWnd)

●选择绘图环境像素格式:ChoosePixelFormat(hDC,&pfd),其中pfd为像素格式

描述符,如果设置不对,OpenGL绘图失败,看不到正确的显示结果。

●设置绘图环境像素格式:SetPixelFormat(hDC,PixelFormat,&pfd)

●获取OpenGL绘图环境:hRC =wglCreateContext(hDC)

●设置OpenGL绘图环境:wglMakeCurrent(hDC,hRC)

(2)空间建模得到3阶魔方

显然,要建立3X3的魔方必须首先建立单个魔方的模型,然后通过对单个立方体进行平移从而得到3X3的魔方。

平移单个立方体通过reset_model( )函数中的语句实现

for(i=0;i<8;i++)

{

Cube[0].CubePoint[i].p[0] = CubePoint[i].p[0]-2.0f ;

Cube[0].CubePoint[i].p[1] = CubePoint[i].p[1]-2.0f ;

Cube[0].CubePoint[i].p[2] = CubePoint[i].p[2]+2.0f;

}

上述代码只得到了编号为0的立方体,其他编号的立方体同理可以得到

构成2X2的魔方需要8个立方体,构建3X3的魔方则需要27个立方体。根据2阶魔方的一些方法,类比到3阶魔方。则首先对魔方的立方体进行编号,然后通过编号得到魔方各层所包含立方体的编号。其中编号为

BYTE ZP[9] = {0,1,2,3,4,5,6,7,8}; //z轴方向正向一层

BYTE ZZ[9] = {9,10,11,12,13,14,15,16,17}; //z轴方向中间一层

BYTE ZM[9] = {18,19,20,21,22,23,24,25,26}; //z轴方向负向一层

BYTE YM[9] = {0,1,2,11,10,9,18,19,20}; //y轴方向负向一层

BYTE YZ[9] = {3,4,5,14,13,12,21,22,23}; //y 轴方向中间一层 BYTE YP[9] = {6,7,8,17,16,15,24,25,26}; //y 轴方向正向一层

BYTE XM[9] = {2,3,8,17,12,11,20,21,26}; //x 轴方向正向一层 BYTE XZ[9] = {1,4,7,16,13,10,19,22,25}; /x 轴方向中间一层 BYTE XP[9] = {0,5,6,15,14,9,18,23,24}; //x 轴方向负向一层 (3)OpenGL 纹理贴图

以下是纹理贴图的流程,其中实现了一个立方体贴六张图片

(4)同步更新索引

在整个程序中,同步更新索引所涉及到的算法可以算是最核心的了。当然,你

也可以让每层每个周期转动360度,这样就不需要动态更新索引了,因为每次转动前后,立方体的相对坐标位置并没有改变。但是这样得到的旋转效果并不好,因为这并没有考虑到魔方旋转的所有情况,每次旋转后魔方都没有被打乱。

由于涉及到动态刷新索引,于是按照常理定义一个静态的魔方与动态的魔方进

行比较。类似动态魔方的编号可以得到静态魔方的编号。

const BYTE

SZP[9] = {0,1,2,3,4,5,6,7,8};

//z 轴方向正向一层

const BYTE SZZ[9] = {9,10,11,12,13,14,15,16,17}; //z轴方向中间一层

const BYTE SZM[9] = {18,19,20,21,22,23,24,25,26}; //z轴方向负向一层

const BYTE SYM[9] = {0,1,2,11,10,9,18,19,20}; //y轴方向负向一层const BYTE SYZ[9] = {3,4,5,14,13,12,21,22,23}; //y轴方向中间一层const BYTE SYP[9] = {6,7,8,17,16,15,24,25,26}; //y轴方向正向一层

const BYTE SXM[9] = {2,3,8,17,12,11,20,21,26}; //x轴方向正向一层const BYTE SXZ[9] = {1,4,7,16,13,10,19,22,25}; //x轴方向中间一层const BYTE SXP[9] = {0,5,6,15,14,9,18,23,24}; //x轴方向负向一层然后编写一个函数int is_equal(stCube *pc1,stCube *pc2)判断两个立方体是否重合,这个函数的算法就是比较立方体所有顶点的坐标是否相同。

最后一步编写函数void Update_Cube_index(),由于魔方转动情况总体上有九种情况,则该函数必须编写九块功能类似的代码,现在只列出X轴负向一层刷新索引的算法。

int i,j,k=0;

k =0 ;

for( i=0;i<9;i++)

{

for( j=0;j<27;j++)

if( is_equal( &Cube[j], &Static_Cube[ SZM[i] ] ) )

{

ZM[k++] = j;

}

}

(5)魔方的旋转以及键盘控制对魔方的平移

魔方层面的旋转已经在前面介绍,此处除了层面旋转还有魔方的整体旋转。只需调用库函数即可即可。

glRotatef(xrot,1.0,0.0,0.0); //使魔方绕x轴转动xrot度glRotatef(yrot,0.0,1.0,0.0); //使魔方绕y轴转动yrot度

glRotatef(zrot,0.0,0.0,1.0); //使魔方绕z轴转动zrot度(6)定时器对魔方层面旋转的控制

为了控制魔方的转动,首先定义了函数void enable_X_roatate(int direction),void enable_Y_roatate(int direction),void enable_Z_roatate(int direction)以确定旋转轴和旋转方向,同时定义了void Rotate_X(int ii),void Rotate_Y(int ii),void Rotate_Z(int ii)来指定是哪一层的旋转。

然后定义两个计时器Time1和Time2,其中Timer1的消息由WM_TIMER接收并处理,以实现立方体的旋转。Timer2的消息由TimerProc函数处理,用于生成控制量以控制旋转轴和旋转方向。

流程如图:

(7)背景音乐的添加

为了程序有更丰富的效果,我添加了歌曲最炫民族风,方法也很简单。

#include //提供与多媒体有关的接口

#pragma comment(lib, "WINMM.LIB") //导入winmm.lib库,实现对多媒体编程的支持

编写函数loadsound(),其调用函数PlaySound("sound\\最炫民族风.wav",NULL,SND_LOOP|SND_ASYNC|SND_FILENAME)加载最炫民族风味背景音乐。

(8)窗口文字的添加

为了添加自己的信息,我在程序窗口中加了文字

void drawString(const char* str),实现添加英文字符。

void drawCNString(const char* str)实现添加中文字符

void selectFont(int size, int charset, const char* face),实现变换字体

2.3 数据结构

本程序定义了记录魔方体每个小块编号的数组Cube[i]及相应的定态数组Static_Cube,用来对魔方体变化过程中的相对位置进行索引及重新定位。定义了立方体记录顶点位置的数组CubePoint[i]及相应静态数组stPoint CubePoint[i],用来确定魔方体的旋转,因为旋转归根结底是其顶点位置的旋转。定义了用来记录魔方体各个面上子块编号的数组ZP/ZZ/ZM,YP/YZ/YM,XP/XZ/XM,及其对应静态数组。定义了数组TextureImage[i]来接收纹理。

2.4 重要函数用法分析

(1)窗口创建

GLvoid resizeScene(GLsizei width,GLsizei height )

这个函数的目的是重置OpenGL窗口的大小,具体又包含以下五个函数

glViewport(0,0,width,height);

glViewport是OpenGL中视口变化函数,根据窗口的实时变化重绘窗口,它负责把视景体截取的图像按照怎样的高和宽显示到屏幕上。

glMatrixMode(GL_PROJECTION)、glMatrixMode(GL_MODELVIEW)

这两个函数原型都是glMatrixMode函数。glMatrixMode这个函数其实就是要指定操作的是哪种矩阵。如果参数是GL_PROJECTION,这个是投影的意思,如果参数是GL_MODELVIEW,这个是对模型视景的操作,用于对三维场景中坐标系的变换操作。

glLoadIdentity()

glLoadIdentity该函数的功能是将当前的用户坐标系的原点移到了屏幕中心,就像一个复位操作

gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f)

gluPerspective的作用是设置透视投影矩阵,意味着越远的东西看起来越小。

45.0f表示将视角设置为45度,(GLfloat)width/(GLfloat)height表示窗口的纵横

比,0.1f表示沿z轴方向的两裁面之间的距离的近处为0.1,100f表示沿z轴方向的两裁面之间的距离的远处为100

(2)初始化操作

glShadeModel(GL_SMOOTH),作用是启用阴影平滑。

glClearColor(0.0f, 0.0f, 0.0f, 0.5f),作用是将背景设置为黑色。

glClearDepth(1.0f),作用是设置深度缓存。

glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST),作用是做精细的透视修正。

loadsound(),作用是导入歌曲最炫民族风。

(3)OpenGL贴图

glGenTextures(1, &texture[i]),作用是利用载入的图像生成纹理。

glBindTexture(GL_TEXTURE_2D, texture[i]),作用是选择生成的纹理。

glTexCoord2f(0.0f,0.0f),作用是设置纹理坐标。

glEnable(GL_TEXTURE_2D),作用是启用纹理映射,此点很关键。

(4)平移与旋转

glTranslatef(x, y, z)

平移函数。表示相对于当前所在的屏幕位置沿着 X, Y 和 Z 轴移动x,y和z 个单位。

glRotatef(angle, x, y, z)

旋转函数。与glTranslatef(x, y, z)类似,glRotatef(angle, x, y, z)也是对坐标系进行操作。旋转轴经过原点,方向为(x,y,z),旋转角度为angle,方向满足右手定则。

(5)添加窗口文字

void drawString(const char* str),实现添加英文字符。

void drawCNString(const char* str)实现添加中文字符

void selectFont(int size, int charset, const char* face),实现变换字体

3.结果演示与程序分析

3.1成果展示

3.2程序分析

3X3魔方有27个小块,对每个小块分别进行编号。先画出一个子块,经过向相应方向的平移,获得完整的魔方体。

魔方由函数glTranslatef(float x,float y,float z)定位,再由函数glRotate(float angle,float x,float y,float z)进行旋转,然后由函数glBindTexture(GLenum target,GLunit textureName)进行纹理与相应面的绑定(纹理已由glGenTextures()函数来产生),最后再用函数glBegin(GL_QUADS)画出正方面,从而描绘出了魔方的一个小面。循环调用就可以绘制出的魔方。

循环调用程序的纹理绑定和旋转过程就实现了魔方体的旋转变化。

4.编程中遇到的问题

在对2X2魔方理解的基础上,我经过自己的摸索终于在末期做出了自己的3阶魔方。其中,遇到了很多问题,不过都被我解决了。以下是我认为的比较重要的问题

(1)在编写判断两个立方体是否重合的函数时,开始我没有消除累计误差。说实话,当时我对这个程序并不是很了解。没有加入这个功能,程序运行结果如下:

刚开始时还比较正常,运行一段时间后,魔方错位了。想了很久,看了指导书才知道原来还差消除累计误差这个功能。其实,这也很好解释。因为我们编写的旋转函数涉及到计算cosa以及sina的值,而计算机计算这些值是不是很准确的。在一个旋转周期中,要计算180次cosa和sina的值,因此误差会被放大,则消除累计误差成了必须。只需判断两个数在一定误差范围内相等即可。

(2)魔方循环控制算法的设计中,我遇到了前所未有的问题。单独编写控制最外面一层或是中间一层旋转的函数确实比较简单,但是如何实现一个实现外层和中间一层同时都可旋转的魔方还是很有难度的,这涉及到如何合理调度的问题。在多方调试后,我想到了一个很好的算法,就是再引入一个控制变量cs,可是变量应该选

择在哪里赋值呢?刚开始我毫不犹豫的就选择在TimerProc函数里面赋值,可是一下子就出错了。后来我将Timer2的定时时间设置为1800ms,目的是等于Timer1的180倍,以实现转一个周期cs重新赋值一次,可结果表明我再次错了。因为转动的延迟,所以转动一个周期所需时间是不定的,但肯定不等于1800ms。在重新阅读一遍程序后,我发现在void Rotate_ZM()函数中有转动一个周期后的初始化操作,受到启发后,我于是将cs的赋值移到了这个函数中,运行了观察很久后都没有出错,果然成功了。

(3)编程过程中还有一些小问题,不过只要是因为C语言编程的一些知识都忘记了,于是我又重新复习了一下C语言的有关知识,果然编起来得心应手多了。5.课程设计小结

编程是一件急需细心和耐心的事,刚开始调试过程中遇到了很多弄不清楚原因的报错现象,但是经过不断地修改,那些问题也都没有了。一开始写3X3程序的时候,为了避免犯错误,我是没有加旋转的,只是建了一个魔方的模型并将其绘制出。

加了旋转函数后果然遇到了一些问题,旋转过程中有时候会出现折叠和重叠现象,经过仔细的检查修改,发现原因是在调用旋转函数时,有部分子块的运动没有写入函数,于是问题得到了部分解决。但是随后编写循环控制算法遇到了很大问题,刚开始都弄烦了,但是休息一段时间后,沉下心来仔细思考,我想到了非常好的控制算法,终于问题全部解决了。

这次课程设计,我确实学到了很多。不仅有提升编程能力,而且也学习到了很多做人的道理。刚开始入手这个项目,感觉压力非常大,因为我之前在3D设计方面还是零基础,OpenGL让我感觉是那么的复杂。随后,我掌握了OpenGL贴图技术,并充分利用OpenGL的特性实现了一个立方体贴六张不同的图片。在我以为实现了一个旋转立方体后,实现2阶魔方就难度不大时,我再次因为我自己的无知而停下了脚步。阅读完老师的代码,总感觉思维很混乱。于是此后很久都没有进展。一段时间过后,当我再次仔细阅读这些算法时,我终于将它们完美的串接了起来,实现了2阶魔方。由2阶魔方到3阶魔方是类似的,但是循环控制算法要难一些。好在我再次编写出来了很好的控制算法,感觉效果很好

总的来说总的来说,本次软件课程设计,对我来说收获不小。不仅复习了C语言知识,也对编程及3D设计产生了一定的兴趣,分析问题和解决问题的能力也得到了不小的提高。而且,我也学到了很多人生的道理。在做一件看似很难的事时,我

们要有一个总体的框架,不要有畏难心理。静下心来,沉着的分析问题,问题总会迎刃而解的。因此,成功的关键在于你是否拥有这样的心理。

参考文献

[1]孙鑫 VC++深入详解第三版北京电子工业出版社 2007年 1-26

[2]杨柏林,陈根浪,徐静 OpenGL编程精粹第三版北京机械工业出版社 2010年 1-121

[3]周纯杰,刘正林,何顶新,周凯波标准C语言程序设计及应用第二版武汉华中科技大学出版社 2008年 1-263

[4]Dave Shreiner,The Khronons OpenGLARB Working Group OpenGL编程指南第七版北京机械工业出版社 2010年 21-328

计算机图形学 实验 利用OpenGL实现图形的平移、旋转、缩放

XXXXXXXX大学(计算机图形学)实验报告 实验名称利用OpenGL实现图形的平移、旋转、缩放 实验时间年月日 专业姓名学号 预习操作座位号 教师签名总评 一、实验目的: 1.了解OpenGL下简单图形的平移、旋转、缩放变换的编程的基本思想; 2.掌握OpenGL下简单图形的平移、旋转、缩放变换的编程的基本步骤; 二、实验原理: 在OpenGL中,可以使用下面三个函数便捷地实现简单图形平移、旋转、缩放变换的功能: glRotatef(theta, vx, vy, vz); glTranslatef(dx, dy, dz); glScalef(sx,sy,sz); 三、实验内容: // 1.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "glut.h" #include "math.h" void display() { glClear( GL_COLOR_BUFFER_BIT); // Clear the frame buffer glColor3f( 0.0, 1.0, 1.0); // Set current color to green glBegin( GL_POLYGON); // Draw the triangle glV ertex2f( 0.0, -0.2); glV ertex2f( 0.2, 0.0); glV ertex2f( 0.0, 0.0); glEnd(); glFlush(); } void dsp()

使用OpenGL画球体

(计算机图形学)实验报告 实验名称使用OpenGL画球体 实验时间年月日 专业班级学号姓名 成绩教师评语: 一、实验目的 1、了解并学习open GL的编程; 2、掌握在open GL生成图形的基本思想和基本步骤; 3、使用open GL具体生成简单的三维立体图形; 二、实验原理 简单的说,该实验就是使用数学函数与OpenGL库中的函数实现图形的生成,比如生成球的函数为x=sin(thetar)*cos(phir); y=cos(thetar)*cos(phir); z=sin(phir); 之后在对thetar的值进行定义,使其在某一范围内变化。然后面的集合就生成了我们所需要的球体,但是该实验没有进行光照和材质的设定,所以看起来并不像一个立体的球体形状。其间还需要对OpenGL的编程原理和其所包含的库比较了解。 OpenGL核心库:Windows: OpenGL32。大多数Unix/Linux系统:GL库(libGL.a) OpenGL实用库(Utility Library, GLU):利用OpenGL核心库提供一些功能,从而避免重复编写代码,与窗口系统的连接 OpenGL实用工具库(OpenGL Utility ToolkitLibrary, GLUT),提供所有窗口系统的共同功能,打开窗口,从鼠标和键盘获取输入,弹出菜单,事件驱动。代码可以在平台间移植,但是GLUT缺乏在特定平台上优秀工具包所具有的功能滚动条。 函数的功能glVertex3f(x, y, z),属于GL库参数个数,x, y, z为float。在glVertex3fv(p)中注意每部分的大小写,p为指向float的指针。 绝大多数常数采用#define在头文件gl.h, glu.h和glut.h中定义。注意#include 会自动包含其它两个头文件。例如:glBegin(GL_POLYGON);glClear(GL_COLOR_BUFFER_BIT);在头文件中也定义了OpenGL数据类型:GLfloat, GLdouble, … 关于最初建立文件的步骤 创建一个win32 console application类型的workspace文件,创建一个C/C++

SU导入3D的流程

Sketchup建模及导入3D的方法及选项设置 用su建模,一是推敲方案,二是在方案推敲完成导入3D后进入后期的渲染,出效果图。 SU建模注意:为了加快建模速度必须设定自己的一套快捷键,在建模的过程中必须每个体量编辑组件,以便以后的修改。为了能导入3D中进行渲染,Sketchup的模型必须面是统一 的,系统默认白色的是正面,蓝色的是反面,就必须把正面朝外反面朝里,要不然在3d里面反面是显示不出来。 第一,第二就是Sketchup 一定是专业版,只有它才能导出3ds格式和dwg格式。 第二,在Sketchup中把材质都赋好,记得一点是不要用Sketchup默认的材质,要新建材质赋你有的jpg格式贴图,这样在3d里面才能继续调整贴图,Sketchup默认的贴 图在3d里可是不认。 第三,就是导出了,在Sketchup里面:文件,导出,3d模型,第一个下拉菜单选所有图层,然后中间的全部都不要选择,最后一个把单位改成毫米就可以了。第一个不动直接确定,第二个点否,现在导进来了,打灯光,打摄像机,调Vary选项。 第四,在Sketchup中赋好的材质,先把模型选中然后在编辑菜单中选Poly Select (可编辑网格选择),下面有几个选项选倒数第二个Polygon,然后在Select By Material ID里面输入相应的材质ID,被选中的材质就会变成红色,这样就可以进行材质的调 整了。 第五,SU导出3DS格式说明:1、Sin gel Object勾选此选项时,整个场景将合并成一个物体被输出,在SketchUP中建立的群组和组件将不能被单独进行操作,在场景中线面数很大的情况 下有可能不能完成输出;(这视情况而定) 2、Objects By Geometry 此选项将以群组和组件为单位输出物体,SketchUP 最表面一层的群组和组件被保留为单独的物体,可以在max中进行单独灵活的各种 编辑,推荐使用。缺点是每一个群组和组件都会输出一个自身的多重子材质 3、Output Texture Maps 如果不勾选,输出材质中将不包含贴图信息;贴图 文件路径需要在max里添加,建议将所有贴图复制到max模型文件所在工作目录, 这样就不会出现找不到贴图的错误信息 4、Output 2-Sides 输出双面:一般情况下不需要,会额外增加模型量;但是 在SketchUP建模阶段必须保证面法线正反的正确性,否则反面在max里无法显示, 产生丢面现象。Materiar和Geometry分别以材质和物体产生双面。 5、Output Standalong Edges 输出边线,对于max 不必要。 6、Use “Color By Layer ” Mater用I层的颜色作为材质输出,是以层颜色进行管 理的材质,需要在建模起始阶段就规划好的材质管理方式,物体(或面)将以所在的层的颜色为自身的材质。因为SketchUP里组件和层是参插的,在组件具有复合 材质时好像不易管理。 7、Gen erate Cameras 产生相机,基本上每一个页面会产生一个相机,这个不用勾 选。

基于OpenGL的3D旋转魔方实现汇总

华中科技大学电子科学与技术系 课程设计报告 ( 2010-- 2011年度第 2 学期) 名称:软件课程设计 题目:基于OpenGL的3D旋转魔方实现 院系: 班级: 学号: 学生姓名: 指导教师: 设计周数: 成绩: 日期:年月日

目录 1.课程设计介绍............................................................................................ (2) 1.1目的.............................................................................................................. (2) 1.2内容.............................................................................................................. (2) 1.3取得的成果 (2) 2.程序分析..................................................................................................... (3) 2.1 程序原理 (3) 2.2 程序流程 (4) 2.3 数据结构 (13) 2.4 重要函数 (13) 3.程序分析与结果演示 (16) 3.1 成果演示 (16) 3.2 程序分析 (17) 4.出现过的问题 (18) 5.心得和小节 (19)

三维模型导入ADAMS的实用方法

三维模型导入ADAMS仿真的实用方法摘要:此文内容主要来源于 宋博士的博客(https://www.sodocs.net/doc/e13329603.html,/doctorsongshaoyun)。 本文所提供的方法是现有ADAMS书籍上未曾提供的内容,是解决大家建模感觉繁琐的非常实用的方法。 下面谈谈我的一些经验:尽管ADAMS软件中提供了几何建模的工具,但相比现在成熟的三维专业设计CAD软件而言其功能非常薄弱。ADAMS/View提供的建模工具功能非常的原始,即使对于简单的几何模型,用户想直接在ADAMS/View中建立也需要非常熟练地掌握移动和旋转工作栅格才能实现,而对于复杂的机械装配模型,ADAMS/View基本无能为力,因此目前通常的做法是先用成熟三维设计软件(如CATIA,UG,Pro/E,Solidwork等)精确建立机械系统实体零件模型和虚拟装配模型,之后通过数据交换的方式(我一般使用parasolid格式)将模型导入到ADAMS软件中,根据实际情况抽象出相应的运动副添加适当的约束、驱动和负载等(此处在正确位置建立合适的Maker点很关键,对于不规则实体有时软件自动建立的cm点并非在仿真需要的地方,运动副位置设置错了容易导致仿真失败)建立起机械系统的虚拟样机,来模拟实际工况和真实运动情况。此外机械系统方面的仿真建议大家使用Adams/Machinery这个插件,可以极大的提高仿真效率。 欢迎访问我的新浪博客(https://www.sodocs.net/doc/e13329603.html,/u/1774643737)。 基于SOLIDWORKS-ADAMS的机构动力学仿真对一个实际的机构做动力学仿真,是我们在机械设计实践中经常会遇到的的问题。一般我们会首先用某款三维软件(如SOLIDWORKS,SOLIDEDGE,PRO/E,UG,CATIA等)对所有零件进行建模,然后把零件组装成为装配体,接着把模型导入到机构动力学软件如ADAMS中进行动力学中仿真。 然而,从三维软件的装配模型导入到ADAMS中时,由于装配体中的零件很多,如果直接导入,会在ADAMS中出现许多零件,而其中许多零件之间并不存在相对运动,为了在ADAMS 中进行正确的仿真,就需要首先对没有相对运动的一系列零件之间建立固定副。对于简单的

DMAX模型导入到Unity3D的步骤

3DMAX模型导入到Unity3D的步骤 1、打开3DMAX,自定义-》单位设置,将系统单位和显示单位都设置为“厘米” 2、建立一个Polygon管状体,参数如下:内径20CM,外径30CM,高30CM 注:保证其坐标原点在0,0,0 3、选中模型右击鼠标转换为可编辑多边形。 多模型进行一些挤出操作。 4、开始导出模型。保持模型选中状态,点击左上角3DMAX图标菜单, 导出-》导出选定对象。导出格式为.FBX,名称必须为英文字母类, 跳出的选项框默认直接确定即可。 例如导出的名称为 5、接下来打开Unity3D,新建立一个项目。 因为是测试项目所以可不导入Unity提供的资源包 6、将之前在3DMAX里导出的模型复制到Unity项目所在文件夹中的Assets文件夹下。 Unity会自动刷新出资源并自动创建一个Materials材质文件夹。如下图示: 7、单击Tube资源,在旁边的Inspector视图中可以看到:Scale Factor的值 表示的比例

8、鼠标拖动Tube到场景中,保持选择状态,摁键盘“F”键,物体自动放大到场景最大 点。3DMAX模型导入到Unity3D的步骤完成。 9、在3DMAX里新建立一个圆柱,系统单位和显示单位仍为CM厘米,圆柱参数如下: 半径100cm,高100cm,模型中心在坐标原点,转换为可编辑多边形, 保存命名为。将复制到Unity项目的Assets文件夹下 10、拖动yuanzhu到主场景。接着在Unity里建立一个圆柱体 Unity里默认是直径1M,高1M的圆柱。我们之前在3DMAX里建立的圆柱半径100cm,导入到Unity后即直径是200cm了。 将Unity里建立的圆柱,Scale参数中的X和Z放大2倍,这个圆柱的半径才是100cm(直径200cm) 然后将从3DMAX里导入的圆柱与Unity里建立的圆柱比较:半径是一样大小的。 说明在3DMAX里建立对应到Unity的模型,系统单位和显示单位设置为“CM”最好。

图形学 用OpenGL实现平移、旋转、缩放

石正坤 一、实验目的: 1.了解OpenGL下简单图形的平移、旋转、缩放变换的编程的基本思想; 2.掌握OpenGL下简单图形的平移、旋转、缩放变换的编程的基本步骤; 二、实验原理: 在OpenGL中,可以使用下面三个函数便捷地实现简单图形平移、旋转、缩放变换的功能: glRotatef(theta, vx, vy, vz); glTranslatef(dx, dy, dz); glScalef(sx,sy,sz); 三、实验内容: // 1.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "glut.h" #include "math.h" void display() {

glClear( GL_COLOR_BUFFER_BIT); // Clear the frame buffer glColor3f( 0.0, 1.0, 1.0); // Set current color to green glBegin( GL_POLYGON); // Draw the triangle glVertex2f( 0.0, -0.2); glVertex2f( 0.2, 0.0); glVertex2f( 0.0, 0.0); glEnd(); glFlush(); } void dsp() { glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BI T); // Clear the frame buffer glColor3f( 0.0, 1.0, 1.0); // Set current color to green display(); //-------------------------- //平移 glPushMatrix(); glTranslatef(0.5,0.5,0.0); display();

OpenGL实现3D模型的交互控制

第24卷第10期 计算机应用与软件 Vol 124No .10 2007年10月 Computer App licati ons and Soft w are Oct .2007 O penG L 实现3D 模型的交互控制 孙妮芳 杨志强 陈 诚 何 斌 龚佩曾 (同济大学计算机系 上海 200092) 收稿日期:2006-12-04。孙妮芳,硕士生,主研领域:虚拟现实技术。 摘 要 简述了3DS 文件的结构,以及在OpenG L 中如何读入和显示3DS 文件的模型,并着重讲述了利用OpenG L 编程接口对场 景中的这些模型进行选择、拾取,通过鼠标拖动对这些模型进行交互操作。关键词 OpenG L 选择 拾取 交互操作 CO NTROL THE 3D MOD EL S I NTERACT I VELY I N O PENGL Sun N ifang Yang Zhiqiang Chen Cheng He B in Gong Peizeng (D epart m ent of Co m puter ,Tongji U niversity,Shanghai 200092,China ) Abstract The structure of 3DS For mat File is outlined,and the way t o read and show the models of 3DS For mat File in OpenG L is p resen 2ted .It is exp lained in detail how the interactive contr ol of the models with the select mode and the feedback mode is realized .Keywords OpenG L Select Picking I nteractive 0 引 言 虚拟实验是当今教育改革比较热门的话题之一,通常意义上讲的虚拟实验建立在真实实验的基础之上,对实验所使用的元器件、,实验者通过鼠标点击与拖曳、键盘操作,可以像对真实元器件一样对虚拟实验设备进行操作,从而完成整个虚拟实验过程。 交互技术是建立虚拟实验要解决的最基本和最重要的问题,交互不仅可以向用户演示信息,同时允许用户向程序传递一些控制信息,比如用户可以通过键盘、鼠标等外设来控制程序的运行。OpenG L 作为一个三维工具软件包,在三维交互编程等方面提供了比较完善的机制。比如,通过OpenG L 的选择、反馈模式比较容易实现通过鼠标键盘进行交互。 目前,已经有不少论文和书籍比较详细地阐述了在OpenG L 中通过选择、拾取和反馈实现对三维物体的交互操作。但对读入和显示多个3DS 文件的模型的交互操作却介绍得比较少。本文根据这一情况并结合实际,在虚拟装机系统中,对场景中的多个元器件模型的交互操作进行详细介绍。 1 3D S 文件介绍 3DS 文件存储了模型的材质信息和几何信息,材质信息主 要包括材质的名称,材质的纹理贴图所对应的文件名以及材质 的颜色等;几何信息主要包括顶点的数目,每个顶点的坐标,三角面的数目,每个三角面上3个顶点的索引,此三角面是否可见等。 3DS 文件由许多块组成,每个块包括信息类别和下一个块的相对位置。块的信息类别用I D 表示,它描述了该块的数据信息。下一个块的相对位置指出了下一个块相对于该块起始位置 的偏移字节数。在块结构中,始终用前2个字节保存I D 号,接下来的4个字节保存块的长度,块的实际内容则用(块长度)6个字节保存。块的内容又可能包含子块。 在OpenG L 中读入3DS 文件的模型的方法有很多,由于本文的程序是在VC ++环境下开发的,所以采用了编写一个类来加载3DS 文件的方法。这样的类很多书籍和网站都有提供,只需进行简单的修改就可以使用,比如修改模型的位置信息以实现模型的移动,增加模型的旋转经度和纬度信息以实现模型的旋转。 2 O penGL 的交互技术 在虚拟装机系统中,要求与场景本身进行更多的交互操作,这种交互除了菜单和对话框实现外,在很多情况下是用鼠标来进行的。OpenG L 的一大功能就是提供了实现交互技术的机制。OpenG L 的交互技术是通过选择、拾取和反馈操作来实现的。 2.1 选 择 选择允许在窗口内部的某个位置用鼠标进行点击,并确定它所点击的是哪个物体。选择是OpenG L 的一种操作模式,选择模式不会改变帧缓存区的内容,退出选择模式时,OpenG L 返回与视景体相交的图元列表,它列出了位于视景体内或与视景体相交的图元,每个图元产生一个选择命中的记录,对应名称堆栈中的当前内容。 ?绘制模式 进入选择模式前,调用函数gl Render M ode (),其原型为:gl Render M ode (G Lenu m mode )。控制应用程序当前所处的模式,即绘图、选择和反馈模式,相应的mode 的取值为G L_RE NDER 、G L _SE LECT 或G L_FEE DBACK 。

OpenGL课程设计-三维球体的实现

游戏软件设计课程报告 (三维球体的实现) 院系: 专业: 学号: 姓名: 指导教师: 2010年10月10日

目录 目录 一、应用程序的最终界面----------------------------------------------------------------1 二、三维球体的绘制---------------------------------------------------------------------2 1、球体绘制方法研究 ----------------------------------------------------------------2 2、面分解法的实现----------------------------------------------------------------3 2.1面分解函数 ----------------------------------------------------------------3 2.2初值的选取 ----------------------------------------------------------------3 2.3 球体的实现----------------------------------------------------------------4 3、三角形绘制函数----------------------------------------------------------------4 4、三角面法向量函数 ----------------------------------------------------------------5 5、点的模长扩展函数 ----------------------------------------------------------------5 6、南北极法的实现----------------------------------------------------------------5 7、动画的实现-------------------------------------------------------------------10 三、二种绘制方法的比较---------------------------------------------------------------12

prescan 3D模型导入步骤

3D模型导入 一.把3D导入PreScan中有步骤: 1.从sketchup软件中导出目标模型文件 1)打开sketchup,右击“文件”——“3D模型库” ——“获取模型”,然后再弹出的模型库页面中 搜索目标模型; 2)选择目标文件并点击下载(保存为.dae格式,只有这个文件prescan才能识别)。 2.把下载下来的目标模型文件添加到prescan用户元素 库中 1)右击prescan上的“Tools”——“User Library Elments Wizard”; 2)弹出的菜单最上面是选择存放路径,下面的选项按钮点击“classic ULE”,然后点击“Add folder” 并对新生成的文件命名; 3)点击新生成的文件来激活对话框右边的“New Element”按钮并点击; 4)在弹出的对话框的第一页给文件命名以及选择元素类型并点击“next”; 5)在弹出的对话框的第二页给添加的心元素命名以及必要的描述并点击“next”; 6)在弹出的对话框的第三页选择第一步骤下载下

来的目标模型文件并点击“next”; 7)第四页是对目标模型进行尺寸设置,一般从sketchup中下载文件都已设置好,可以直接点 击“next”; 8)下面只要顺着点击“next”即可,最后点击“User Library Elments Wizard”对话框上的“refersh and close”就能在prescan的UL Elements中直接拖 拉该模型放置场景中。 注意:1)在3D模型库中下载的文件需有 textures.txt文件,不然导入的在3D viewer中看 到的模型将是一片漆黑。

基于openGl的三维旋转魔方源代码

基于openGl的三维旋转魔方源代码/* * This Code Was Created By Jeff Molofee 2000 * A HUGE Thanks To Fredric Echols For Cleaning Up * And Optimizing The Base Code, Making It More Flexible! * If You've Found This Code Useful, Please Let Me Know. * Visit My Site At https://www.sodocs.net/doc/e13329603.html, */ // Header File For Standard Input/Output #include "MoFang.h" HDC hDC=NULL; // Private GDI Device Context HGLRC hRC=NULL; // Permanent Rendering Context HWND hWnd=NULL; // Holds Our Window Handle HINSTANCE h Instance; // Holds The Instance Of The Application bool keys[256]; // Array Used For The Keyboard Routine bool active=TRUE; // Window Active Flag Set To TRUE By Default bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default GLfloat xrot; // X Rotation ( NEW ) GLfloat yrot; // Y Rotation ( NEW ) GLfloat zrot; // Z Rotation ( NEW ) GLfloat RX; GLfloat RY; GLuint texture[24]; // Storage For One Texture ( NEW ) GLboolean b_RX,b_RY; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image { FILE *File=NULL; // File Handle if (!Filename) // Make Sure A Filename Was Given

Quest3D模型的导入教程

一、前期准备工作(本教程以3DSMax为建模工具作为使用参考) 1.使用3DSMax创作一个最简单的茶壶模式: 2.在File(文件)菜单栏中选择运行Export(输出)命令,然后在Select File to Export(选择输出文件)对话框中选择Quest3D公司自己开发支持的X文件格式,选定后点击"完成"按钮: 3.在"场景统计和文件选项"对话框中选择并完成相应的设置: 4.Quest3D公司为3DSMax开发的X文件输出插件会自动将模型保存为X文件,本实例中将文件名设置保存为teaport.X.

二、在Quest3D中导入模型: 1.双击快捷图标运行Quest3D程序,在File(文件)菜单栏中选择运行Import导入命令: 2.在Select File to Import(选择输入文件)对话框中选择teaport.x文件: 3.Quest3D在点击导入文件对话框中的"打开"按钮后会弹出X Object Importer Options(X对象导入选项)对话框,进行相应的载入类型和选项设置.完成设置后点击"OK"确认按钮:

4、在Load Channel Group(载入通道组合)警告提示框,用以确定文件名和文件类型,: 5、当Channel通道窗口中出现DX8 3D Object相应的模型结构关系图后,就完成了模型的导入任务: 三、在动画窗口正常显示3D模型 出现问题:当我们完成第二步骤的工作以后,却发现在动画窗口中看不到相应的模型,这就意味着在Run预览运行效果和打包输出后一无所见! 这可是一个及其严重的问题哟,怎么办呢,解决方法如下: 1.在template模板窗口中,拖动Quick Start中的ObjectInspectiong的链接到Channel通道窗口:

提取3D游戏模型的方法

提取3D游戏模型的方法 网络游戏工具【GameAssassin】是一个针对网络游戏和3D游戏的辅助工具,具有设置3D游戏的线框显示模式,截获3D游戏的模型贴图数据等功能,针对于网络游戏,此软件能够接获游戏所发出并且接受的网络消息,并且能够向服务器直接发送外部的自定义数据。 如果想截游戏模型,首先要到GA的官方下载相关软件和插件。 只需下载GA和导入MAX用的插件就可以。 首先是激活功能,这是必须做的一步,然后尽先一下简单的设置(如图) 再将游戏在任务栏上的完整名称输入到“自定义截取”中。然后在进入游戏。 切记是先运行GA再运行游戏,如果无法确认游戏的名称 可以在运行GA之前先运行游戏,记住游戏在任务栏上的名称 如果名称太长,显示不完整,可以查看任务管理器,确认后退出游戏。 在顺利进入游戏以后,我们会在屏幕的左上角看到“GA”两个彩色字母,这就说明在本游戏中GA运行成功,如果没有显示,就说明没有成功,就无法进行截取(如果不显示的话,就试着Alt+Tab切到GA主截面,选中游戏名称,点击“截取”,如果还不显示,可能就是操作步骤出现了错误)。如果没什么问题,就按下热键Alt+F7截取模型。 【建议在模型比较少的界面下截取,例如选人截面】

按下热键后,我们切到GA的主目录观察文件夹“魔兽世界”中是否已经生成OBJ模型文件,如果什么都没有,就再切回来,再按两遍热键。如果还没有OBJ文件,或是出现“非法操作”的话,那么退出GA,从新截取游戏。

如果没问题了,那么我们就进入模型观察器3D View中,将主人公的模型碎片从新组合,选择你认为是主人公身体一部分的模型,将其添加到组合物体中去。(如果在选取模型碎片文件时提示模型打开失败的话,那么建议你换个显卡。) 拼合好模型后,如果没问题的话,就将组合好的模型保存为列表文件

opengl旋转球程序

#include #include #include #include #include #include #include static GLfloat xAngle = 0.0f; static GLfloat yAngle = 0.0f; //定义旋转角度 #define PI 3.1415926 typedef struct point { float x,y,z; }PT; struct point p[2][1000]; void Initial(void) { GLfloat mat_ambient[]={0.2f,0.2f,0.2f,1.0f}; GLfloat mat_diffuse[]={0.8f,0.8f,0.8f,1.0f}; GLfloat mat_specular[]={1.0f,1.0f,1.0f,1.0f}; GLfloat mat_shininess[]={50.0f}; GLfloat light0_diffuse[]={0.0f,0.0f,1.0f,1.0f}; GLfloat light0_position[]={1.0f,1.0f,1.0f,0.0f}; GLfloat light1_ambient[]={0.2f,0.2f,0.2f,1.0f}; GLfloat light1_diffuse[]={1.0f,0.0f,0.0f,1.0f}; GLfloat light1_specular[]={1.0f,0.6f,0.6f,1.0f}; GLfloat light1_position[]={-2.0f,-2.0f,1.0f,0.0f}; GLfloat spot_direction[]={1.0f,1.0f,-1.0f}; //定义材质属性 glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); //指定材质的环境反射光反射系数 glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); //指定材质的漫反射光反射系数 glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); //指定材质的镜面反射光反射系数 glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); //指定材质的镜面发射指数值 //light0为漫反射的蓝色点光源 glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse); //指定漫反射光成分 glLightfv(GL_LIGHT0,GL_POSITION,light0_position); //设置光源的位置 //light1为红色聚光光源 glLightfv(GL_LIGHT1,GL_AMBIENT,light1_ambient); //指定环境光成分 glLightfv(GL_LIGHT1,GL_DIFFUSE,light1_diffuse); //指定漫反射光成分 glLightfv(GL_LIGHT1,GL_SPECULAR,light1_specular); //指定镜面光成分

实验五 OpenGL坐标变换

1.实验五OpenGL坐标变换(选做) 1.实验五:OpenGL坐标变换。 2.实验目的:通过上机编程,熟悉OpenGL程序的基本框架,掌握OpenGL基本图元 的绘制方法和OpenGL图形坐标的变换方法,理解坐标变换的原理。 3.实验要求: (1)每人一组,独立完成。 (2)构架一个OpenGL程序框架,绘制两个茶壶,一个先平移再旋转,一个先旋转再平移,比较两个茶壶因坐标变换次序不同而产生的不同效果。 说明:从本实验开始,很多实验都需要参考《三维游戏设计师宝典——学OpenGL 编3D游戏》一书,该书按章节提供了对应的源代码。 4.实验原理及内容: (1)OpenGL是输出到图形硬件的一个软件编程接口,它定义了一个独立于语言的图形核心系统,编程时调用其提供的API函数即可。 (2)Visual C++ 6.0环境中的OpenGL程序基本框架: 在Windows操作系统下编制OpenGL程序,必需先建立Windows框架,然后再在Windows框架下建立OpenGL的框架(“A01_OpenGL的程序框架”文件夹中 就包含了一个这样的完整框架程序,后面的实验都将使用这个程序框架),其中:Windows框架主要由三个函数构建: a)WinMain():主程序入口,程序从这里开始运行,它定义了一个Windows 的窗口的样式、大小等等,并建立这个窗口。 b)MsgProc():消息处理函数。Windows程序是基于事件响应的运行机制, 该函数在整个运行周期中随时对其所定义的外部事件(如鼠标移动、点 击、窗口变化、键盘,以及其它函数发出的消息)做出反应。 c)GameLoop():消息循环。这是利用Windows的消息机制做成的主循环 函数,它被程序反复执行,OpenGL的图形处理函数Render()就在其中 被调用。GameLoop()函数的作用是侦听消息,有消息时返回Windows 的消息链,没有消息时就执行Render()。 OpenGL的基本框架由四个函数组成,与Windows框架的调用关系参见图5-1:

OpenGL 球面相机旋转算法

旋转作为三维开发的基本功能,在任何3D程序中都需要。用户通过旋转来实现对模型各个面的浏览,形成直观印象。 球面相机旋转 这种旋转方式用户体验方式要优于x轴y轴混合旋转方式,模型旋转的方向和鼠标移动方向保持一致。 下面给出一种“球面相机”实现旋转的方法。 原理: 移动鼠标时,通过gluLookAt来改变视点的位置(采用增量的方式),而模型保持不动。即:只进行视点变换,不进行模型变换。 下图是用户按下左键,在屏幕上移动的一段距离(从A移动到B)。 由于屏幕坐标y轴向下,为了与投影平面坐标系(传统笛卡尔坐标)保持一致。 AM = y1-y2; /*将消息代码描述*/ BM = x2-x1; 建立屏幕和投影变换近裁截面之间的对应关系(如下图)。

代码实现: 1 void setSphereCameraPos() 2 { 3 // 左键未按下,直接返回 4 if (!is_left_button_down) 5 return; 6 7 // 从聚焦点指向视点的向量 OA向量 8 vector3dd a(eye-target); 9 10 // 计算球面相机半径 11 radius = a.getLength();

12 13 // 将其单位化 14 a.normailize(); 15 16 // 当前相机向上方向与a做叉乘,计算投影面水平向右方向向量u 17 vector3dd u = upvector.crossProduct(a); 18 // 将其单位化 19 u.normailize(); 20 21 // 计算相机向上方向在投影面上的投影向量即垂直向上的方向向量v 22 vector3dd v = a.crossProduct(u); 23 // 将其单位化 24 v.normailize(); 25 26 // 计算屏幕AB在投影面上对应的向量 AB向量 27 vector3dd m = u*delta_point.x + v*delta_point.y; 28 29 // 计算m向量的长度 30 double len = m.getLength(); 31 // 降低灵敏度 32 len /= 20.0; 33 34 if (len>0.0) 35 { 36 // 角度AOB 弧度表示弧长/半径 37 double x = len/radius;

OpenGL实现3D模型的交互控制

1 3DS文件介绍 3DS文件存储了模型的材质信息和几何信息,材质信息主要包括材质的名称,材质的纹理贴图所对应的文件名以及材质的颜色等;几何信息主要包括顶点的数目,每个顶点的坐标,三角面的数目,每个三角面上3个顶点的索引,此三角面是否可见等。 3DS文件由许多块组成,每个块包括信息类别和下一个块的相对位置。块的信息类别用ID表示,它描述了该块的数据信息。下一个块的相对位置指出了下一个块相对于该块起始位置的偏移字节数。在块结构中,始终用前2个字节保存D号,接下来的4个字节保存块的长度,块的实际内容则用(块长度)6个字节保存。块的内容又可能包含子块。 在OpenGL中读入3DS文件的模型的方法有很多,由于本文的程序是在VC + +环境下开发的,所以采用了编写一个类来加载3DS文件的方法。这样的类很多书籍和网站都有提供,只需进行简单的修改就可以使用,比如修改模型的位置信息以实现模型的移动,增加模型的旋转经度和纬度信息以实现模型的旋转。 1 OpenGL的交互技术 在虚拟装机系统中,要求与场景本身进行更多的交互操作,这种交互除了菜单和对话框实现外,在很多情况下是用鼠标来进行的。OperGL的一大功能就是提供了实现交互技术的机制。 OperGL的交互技术是通过选择、拾取和反馈操作来实现的。 2 1选择 选择允许在窗口内部的某个位置用鼠标进行点击,并确定它所点击的是哪个物体。选择是OpenGL的一种操作模式,选择模式不会改变帧缓存区的内容,退出选择模式时,OperGL返回与视景体相交的图元列表,它列出了位于视景体内或与视景体相交的图元,每个图元产生一个选择命中的记录,对应名称堆栈中的当前内容。 绘制模式进入选择模式前,调用函数gR endeM ode (),其原型为:gRendeMode(GLmum mode)。控制应用程序当前所处的模式,即绘图、选择和反馈模式,相应的mode的取值为 GL—RENDER、GL—SELECT 或 GL—FEEDBACK。 ?创建名称堆栈名称堆栈的内容可以用来确定用户选择的物体,所以它在选择操作中具有非常重要的作用。首先,用 gUnitNaneS()函数初始化名称堆栈,即清除名称堆栈。然后,在发出各模型绘图命令的同时,用gPuthName()函数将物体名称压入堆栈。这名称是整数,OpenGL可以包含64个名称。 操作堆栈的函数有: gIPushName()函数,将名称压入堆栈; gPcpNam e()函数,将名称从堆栈中弹出; gLoadName()函数,用不同的名称替换最顶层堆栈的名称。 /淀义模型数组 //3D模型定义 /第一个模型

SU 导入3D的流程PDF.pdf

书山有路 Sketchup建模及导入3D的方法及选项设置 用su 建模,一是推敲方案,二是在方案推敲完成导入3D后进入后期的渲染,出效果图。SU建模注意:为了加快建模速度必须设定自己的一套快捷键,在建模的过程中必须每个体量编辑组件,以便以后的修改。为了能导入3D中进行渲染,Sketchup的模型必须面是统一的,系统默认白色的是正面,蓝色的是反面,就必须把正面朝外反面朝里,要不然在3d里面反面是显示不出来。 第一,第二就是Sketchup一定是专业版,只有它才能导出3ds格式和dwg格式。 第二,在Sketchup中把材质都赋好,记得一点是不要用Sketchup默认的材质,要新建材质赋你有的jpg格式贴图,这样在3d里面才能继续调整贴图,Sketchup默认的贴 图在3d里可是不认。 第三,就是导出了,在Sketchup里面:文件,导出,3d模型,第一个下拉菜单选所有图层,然后中间的全部都不要选择,最后一个把单位改成毫米就可以了。第一个不动 直接确定,第二个点否,现在导进来了,打灯光,打摄像机,调Vary选项。 第四,在Sketchup中赋好的材质,先把模型选中然后在编辑菜单中选Poly Select(可编辑网格选择),下面有几个选项选倒数第二个Polygon,然后在Select By Material ID里面输入相应的材质ID,被选中的材质就会变成红色,这样就可以进行材质的调整了。 第五,SU导出3DS格式说明:1、Singel Object 勾选此选项时,整个场景将合并成一个物体被输出,在SketchUP中建立的群组和组件将不能被单独进行操作,在场景 中线面数很大的情况下有可能不能完成输出;(这视情况而定) 2、Objects By Geometry 此选项将以群组和组件为单位输出物体,SketchUP 最表面一层的群组和组件被保留为单独的物体,可以在max中进行单独灵活的各种编辑,推荐使用。缺点是每一个群组和组件都会输出一个自身的多重子材质. 3、Output Texture Maps 如果不勾选,输出材质中将不包含贴图信息;贴图 文件路径需要在max里添加,建议将所有贴图复制到max模型文件所在工作目录,这样就不会出现找不到贴图的错误信息 4、Output 2-Sides 输出双面:一般情况下不需要,会额外增加模型量;但是 在SketchUP建模阶段必须保证面法线正反的正确性,否则反面在max里无法显示,产生丢面现象。Materiar和Geometry分别以材质和物体产生双面。 5、Output Standalong Edges 输出边线,对于max不必要。 6、Use “Color By Layer”Material 用层的颜色作为材质输出,是以层颜色进行管 理的材质,需要在建模起始阶段就规划好的材质管理方式,物体(或面)将以所在 的层的颜色为自身的材质。因为SketchUP里组件和层是参插的,在组件具有复合 材质时好像不易管理。 7、Generate Cameras 产生相机,基本上每一个页面会产生一个相机,这个不 用勾选。 1

相关主题